From 167355337e3af9d06a21f4fdbdfe1f5d034e575f Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Mon, 29 Oct 2018 02:55:24 +0100 Subject: [PATCH] Ref T412, Ref T227, own aircraft positions and state detection * keep history of own positions * detect moved aircraft * relay signals via proxy --- src/blackcore/context/contextownaircraft.h | 9 ++ .../context/contextownaircraftimpl.cpp | 90 ++++++++++++++++--- .../context/contextownaircraftimpl.h | 24 ++++- .../context/contextownaircraftproxy.cpp | 14 ++- .../context/contextownaircraftproxy.h | 4 +- 5 files changed, 119 insertions(+), 22 deletions(-) diff --git a/src/blackcore/context/contextownaircraft.h b/src/blackcore/context/contextownaircraft.h index af1e16305..47eaf20a5 100644 --- a/src/blackcore/context/contextownaircraft.h +++ b/src/blackcore/context/contextownaircraft.h @@ -102,9 +102,18 @@ namespace BlackCore //! Own pilot (aka the swift user) changed void changedPilot(const BlackMisc::Network::CUser &pilot); + //! Changed aircraft model + void changedModel(const BlackMisc::Simulation::CAircraftModel &model); + //! Aircraft has been moved from one location to another (changed scenery) void movedAircraft(); + //! Just airborne + void airborne(); + + //! Just landed + void touchdown(); + public slots: //! Get own aircraft virtual BlackMisc::Simulation::CSimulatedAircraft getOwnAircraft() const = 0; diff --git a/src/blackcore/context/contextownaircraftimpl.cpp b/src/blackcore/context/contextownaircraftimpl.cpp index 9ff52c600..d5e64a002 100644 --- a/src/blackcore/context/contextownaircraftimpl.cpp +++ b/src/blackcore/context/contextownaircraftimpl.cpp @@ -7,31 +7,36 @@ * contained in the LICENSE file. */ -#include "blackcore/db/databaseutils.h" +#include "blackcore/context/contextownaircraftimpl.h" + +// ----- cross context ----- #include "blackcore/context/contextapplication.h" #include "blackcore/context/contextaudio.h" #include "blackcore/context/contextnetwork.h" -#include "blackcore/context/contextownaircraftimpl.h" +#include "blackcore/context/contextsimulator.h" +// ----- cross context ----- + #include "blackcore/application.h" #include "blackcore/webdataservices.h" #include "blackmisc/audio/voiceroom.h" #include "blackmisc/audio/voiceroomlist.h" +#include "blackmisc/network/server.h" #include "blackmisc/aviation/aircrafticaocode.h" #include "blackmisc/aviation/aircraftsituation.h" #include "blackmisc/aviation/altitude.h" #include "blackmisc/aviation/callsign.h" #include "blackmisc/aviation/transponder.h" -#include "blackmisc/compare.h" -#include "blackmisc/dbusserver.h" +#include "blackcore/db/databaseutils.h" +#include "blackmisc/pq/physicalquantity.h" #include "blackmisc/geo/latitude.h" #include "blackmisc/geo/longitude.h" +#include "blackmisc/pq/units.h" +#include "blackmisc/simplecommandparser.h" +#include "blackmisc/compare.h" +#include "blackmisc/dbusserver.h" #include "blackmisc/logcategory.h" #include "blackmisc/logmessage.h" -#include "blackmisc/network/server.h" -#include "blackmisc/pq/physicalquantity.h" -#include "blackmisc/pq/units.h" #include "blackmisc/sequence.h" -#include "blackmisc/simplecommandparser.h" #include "blackmisc/statusmessage.h" #include @@ -57,7 +62,13 @@ namespace BlackCore CIdentifiable(this) { Q_ASSERT(this->getRuntime()); + + connect(&m_historyTimer, &QTimer::timeout, this, &CContextOwnAircraft::evaluateUpdateHistory); this->setObjectName("CContextOwnAircraft"); + m_historyTimer.setObjectName(this->objectName() + "::historyTimer"); + m_historyTimer.start(2500); + m_situationHistory.setSortHint(CAircraftSituationList::TimestampLatestFirst); + CContextOwnAircraft::registerHelp(); if (sApp && sApp->getWebDataServices()) @@ -175,6 +186,35 @@ namespace BlackCore emit this->getIContextApplication()->fakedSetComVoiceRoom(rooms); } + void CContextOwnAircraft::evaluateUpdateHistory() + { + if (!m_history) { return; } + if (!this->getIContextSimulator()) { return; } + + if (this->getIContextSimulator()->isSimulatorSimulating()) + { + if (!m_situationHistory.isEmpty()) + { + QReadLocker rl(&m_lockAircraft); + const CAircraftSituationList situations = m_situationHistory; + rl.unlock(); + + // using copy to minimize lock time + // 500km/h => 1sec: 0.1388 km + static const CLength maxDistance(25, CLengthUnit::km()); + const bool jumpDetected = situations.containsObjectOutsideRange(situations.front(), maxDistance); + + if (jumpDetected) + { + emit this->movedAircraft(); + QWriteLocker wl(&m_lockAircraft); + m_situationHistory.clear(); + } + + } + } // only if simulating + } + CAircraftModel CContextOwnAircraft::reverseLookupModel(const CAircraftModel &model) { bool modified = false; @@ -185,10 +225,15 @@ namespace BlackCore bool CContextOwnAircraft::updateOwnModel(const CAircraftModel &model) { CAircraftModel updateModel(this->reverseLookupModel(model)); - QWriteLocker l(&m_lockAircraft); - const bool changed = (m_ownAircraft.getModel() != updateModel); - if (!changed) { return false; } - m_ownAircraft.setModel(updateModel); + { + QWriteLocker l(&m_lockAircraft); + const bool changed = (m_ownAircraft.getModel() != updateModel); + if (!changed) { return false; } + m_ownAircraft.setModel(updateModel); + } + + // changed model + emit this->changedModel(model); return true; } @@ -197,6 +242,12 @@ namespace BlackCore QWriteLocker l(&m_lockAircraft); // there is intentionally no equal check m_ownAircraft.setSituation(situation); + + if (m_situationHistory.isEmpty() || qAbs(situation.getTimeDifferenceMs(m_situationHistory.front())) > MinHistoryDeltaMs) + { + m_situationHistory.push_frontKeepLatestAdjustedFirst(situation, true); + if (m_situationHistory.size() > MaxHistoryElements) { m_situationHistory.pop_back(); } + } return true; } @@ -337,6 +388,21 @@ namespace BlackCore this->updateOwnModel(model); } + void CContextOwnAircraft::xCtxChangedSimulatorStatus(int status) + { + const ISimulator::SimulatorStatus s = static_cast(status); + if (ISimulator::isAnyConnectedStatus(s)) + { + // connected + } + else + { + // disconnected + QWriteLocker l(&m_lockAircraft); + m_situationHistory.clear(); + } + } + void CContextOwnAircraft::allSwiftWebDataRead() { // we should already have received a reverse lookup model diff --git a/src/blackcore/context/contextownaircraftimpl.h b/src/blackcore/context/contextownaircraftimpl.h index ea20f2188..43c13649b 100644 --- a/src/blackcore/context/contextownaircraftimpl.h +++ b/src/blackcore/context/contextownaircraftimpl.h @@ -21,6 +21,7 @@ #include "blackmisc/simulation/aircraftmodel.h" #include "blackmisc/simulation/ownaircraftprovider.h" #include "blackmisc/simulation/simulatedaircraft.h" +#include "blackmisc/aviation/aircraftsituationlist.h" #include "blackmisc/aviation/aircraftparts.h" #include "blackmisc/aviation/airlineicaocode.h" #include "blackmisc/aviation/atcstation.h" @@ -37,6 +38,8 @@ #include #include #include +#include +#include namespace BlackMisc { @@ -180,10 +183,16 @@ namespace BlackCore private: BlackMisc::Simulation::CSimulatedAircraft m_ownAircraft; //!< my aircraft - bool m_automaticVoiceRoomResolution = true; //!< automatic voice room resolution, or disable for override - QString m_voiceRoom1UrlOverride; //!< overridden voice room url - QString m_voiceRoom2UrlOverride; //!< overridden voice room url - mutable QReadWriteLock m_lockAircraft; //!< lock aircraft + bool m_automaticVoiceRoomResolution = true; //!< automatic voice room resolution, or disable for override + QString m_voiceRoom1UrlOverride; //!< overridden voice room url + QString m_voiceRoom2UrlOverride; //!< overridden voice room url + mutable QReadWriteLock m_lockAircraft; //!< lock aircraft + + static constexpr qint64 MinHistoryDeltaMs = 1000; + static constexpr int MaxHistoryElements = 20; + QTimer m_historyTimer; //!< history timer + std::atomic_bool m_history { true }; //!< enable history + BlackMisc::Aviation::CAircraftSituationList m_situationHistory; //!< history, latest situation first BlackMisc::CSetting m_currentNetworkServer { this }; @@ -195,6 +204,10 @@ namespace BlackCore //! \ingroup crosscontextfunction void xCtxChangedSimulatorModel(const BlackMisc::Simulation::CAircraftModel &model); + //! Simulator status changed + //! \ingroup crosscontextfunction + void xCtxChangedSimulatorStatus(int status); + //! Web data loaded void allSwiftWebDataRead(); @@ -204,6 +217,9 @@ namespace BlackCore //! Resolve voice rooms void resolveVoiceRooms(); + //! Update position history + void evaluateUpdateHistory(); + //! Reverse lookup of the model against DB data static BlackMisc::Simulation::CAircraftModel reverseLookupModel(const BlackMisc::Simulation::CAircraftModel &model); }; diff --git a/src/blackcore/context/contextownaircraftproxy.cpp b/src/blackcore/context/contextownaircraftproxy.cpp index 8f05ea097..69089cc81 100644 --- a/src/blackcore/context/contextownaircraftproxy.cpp +++ b/src/blackcore/context/contextownaircraftproxy.cpp @@ -8,6 +8,7 @@ */ #include "blackcore/context/contextownaircraftproxy.h" +#include "blackmisc/simulation/aircraftmodel.h" #include "blackmisc/dbus.h" #include "blackmisc/dbusserver.h" #include "blackmisc/genericdbusinterface.h" @@ -38,25 +39,30 @@ namespace BlackCore bool s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(), "changedAircraftCockpit", this, SIGNAL(changedAircraftCockpit(BlackMisc::Simulation::CSimulatedAircraft, BlackMisc::CIdentifier))); Q_ASSERT(s); - s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(), "changedSelcal", this, SIGNAL(changedSelcal(BlackMisc::Aviation::CSelcal, BlackMisc::CIdentifier))); Q_ASSERT(s); - s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(), "changedCallsign", this, SIGNAL(changedCallsign(BlackMisc::Aviation::CCallsign))); Q_ASSERT(s); - s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(), "changedAircraftIcaoCodes", this, SIGNAL(changedAircraftIcaoCodes(BlackMisc::Aviation::CAircraftIcaoCode, BlackMisc::Aviation::CAirlineIcaoCode))); Q_ASSERT(s); - s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(), "changedPilot", this, SIGNAL(changedPilot(BlackMisc::Network::CUser))); Q_ASSERT(s); + s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(), + "changedModel", this, SIGNAL(changedModel(BlackMisc::Simulation::CAircraftModel))); + Q_ASSERT(s); s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(), "movedAircraft", this, SIGNAL(movedAircraft())); Q_ASSERT(s); + s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(), + "airborne", this, SIGNAL(airborne())); + Q_ASSERT(s); + s = connection.connect(serviceName, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName(), + "touchdown", this, SIGNAL(touchdown())); + Q_ASSERT(s); this->relayBaseClassSignals(serviceName, connection, IContextOwnAircraft::ObjectPath(), IContextOwnAircraft::InterfaceName()); Q_UNUSED(s); diff --git a/src/blackcore/context/contextownaircraftproxy.h b/src/blackcore/context/contextownaircraftproxy.h index 00fc819cc..30594448f 100644 --- a/src/blackcore/context/contextownaircraftproxy.h +++ b/src/blackcore/context/contextownaircraftproxy.h @@ -15,9 +15,10 @@ #include #include -#include "blackcore/blackcoreexport.h" #include "blackcore/context/contextownaircraft.h" #include "blackcore/corefacadeconfig.h" +#include "blackcore/blackcoreexport.h" +#include "blackmisc/simulation/simulatedaircraft.h" #include "blackmisc/aviation/airlineicaocode.h" #include "blackmisc/aviation/comsystem.h" #include "blackmisc/aviation/selcal.h" @@ -25,7 +26,6 @@ #include "blackmisc/identifier.h" #include "blackmisc/network/user.h" #include "blackmisc/pq/frequency.h" -#include "blackmisc/simulation/simulatedaircraft.h" class QDBusConnection;