From 848da69fe13bcd1af22c1840ce391e87e88e6758 Mon Sep 17 00:00:00 2001 From: Roland Winklmeier Date: Sat, 14 Apr 2018 20:25:54 +0200 Subject: [PATCH] Group sending of all plane positions and surfaces into a single DBus call --- .../simulator/xplane/simulatorxplane.cpp | 119 ++++++++--- .../simulator/xplane/simulatorxplane.h | 6 - .../xplane/xswiftbustrafficproxy.cpp | 50 +++-- .../simulator/xplane/xswiftbustrafficproxy.h | 26 ++- src/xswiftbus/dbusmessage.cpp | 62 ++++++ src/xswiftbus/dbusmessage.h | 4 + .../org.swift_project.xswiftbus.traffic.xml | 42 ++-- src/xswiftbus/traffic.cpp | 202 ++++++++++++------ src/xswiftbus/traffic.h | 23 +- 9 files changed, 374 insertions(+), 160 deletions(-) diff --git a/src/plugins/simulator/xplane/simulatorxplane.cpp b/src/plugins/simulator/xplane/simulatorxplane.cpp index 00edb92ee..0b6b360ec 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.cpp +++ b/src/plugins/simulator/xplane/simulatorxplane.cpp @@ -117,8 +117,23 @@ namespace BlackSimPlugin bool CSimulatorXPlane::requestElevation(const ICoordinateGeodetic &reference, const CCallsign &callsign) { - //! \todo KB 2018-04 implement a function fetching the probe value (async) and write it back to provider - return ISimulator::requestElevation(reference, callsign); + if (this->isShuttingDown()) { return false; } + if (reference.isNull()) { return false; } + + static const CAltitude alt(50000, CLengthUnit::ft()); + CCoordinateGeodetic pos(reference); + pos.setGeodeticHeight(alt); + + using namespace std::placeholders; + auto callback = std::bind(&CSimulatorXPlane::callbackReceivedRequestedElevation, this, _1, _2); + + // Request + m_trafficProxy->getEelevationAtPosition(callsign, + pos.latitude().value(CAngleUnit::deg()), + pos.longitude().value(CAngleUnit::deg()), + pos.geodeticHeight().value(CLengthUnit::m()), + callback); + return true; } // convert xplane squawk mode to swift squawk mode @@ -246,6 +261,7 @@ namespace BlackSimPlugin connect(m_trafficProxy, &CXSwiftBusTrafficProxy::simFrame, this, &CSimulatorXPlane::updateRemoteAircraft); connect(m_trafficProxy, &CXSwiftBusTrafficProxy::remoteAircraftData, this, &CSimulatorXPlane::updateRemoteAircraftFromSimulator); if (m_watcher) { m_watcher->setConnection(m_conn); } + m_trafficProxy->removeAllPlanes(); this->loadCslPackages(); this->emitSimulatorCombinedStatus(); return true; @@ -671,6 +687,33 @@ namespace BlackSimPlugin // interpolation for all remote aircraft const QList xplaneAircraftList(m_xplaneAircraftObjects.values()); + + QStringList posCallsigns; + QList latitudes; + QList longitudes; + QList altitudes; + QList pitches; + QList rolles; + QList headings; + + QStringList surfaceCallsign; + QList gear; + QList flap; + QList spoiler; + QList speedBrake; + QList slat; + QList wingSweep; + QList thrust; + QList elevator; + QList rudder; + QList aileron; + QList landLight; + QList beaconLight; + QList strobeLight; + QList navLight; + QList lightPattern; + QList onGround; + for (const CXPlaneMPAircraft &xplaneAircraft : xplaneAircraftList) { const CCallsign callsign(xplaneAircraft.getCallsign()); @@ -689,13 +732,13 @@ namespace BlackSimPlugin if (!xplaneAircraft.isSameAsSent(interpolatedSituation)) { m_xplaneAircraftObjects[xplaneAircraft.getCallsign()].setSituationAsSent(interpolatedSituation); - m_trafficProxy->setPlanePosition(interpolatedSituation.getCallsign().asString(), - interpolatedSituation.latitude().value(CAngleUnit::deg()), - interpolatedSituation.longitude().value(CAngleUnit::deg()), - interpolatedSituation.getAltitude().value(CLengthUnit::ft()), - interpolatedSituation.getPitch().value(CAngleUnit::deg()), - interpolatedSituation.getBank().value(CAngleUnit::deg()), - interpolatedSituation.getHeading().value(CAngleUnit::deg())); + posCallsigns.push_back(interpolatedSituation.getCallsign().asString()); + latitudes.push_back(interpolatedSituation.latitude().value(CAngleUnit::deg())); + longitudes.push_back(interpolatedSituation.longitude().value(CAngleUnit::deg())); + altitudes.push_back(interpolatedSituation.getAltitude().value(CLengthUnit::ft())); + pitches.push_back(interpolatedSituation.getPitch().value(CAngleUnit::deg())); + rolles.push_back(interpolatedSituation.getBank().value(CAngleUnit::deg())); + headings.push_back(interpolatedSituation.getHeading().value(CAngleUnit::deg())); } } else @@ -703,40 +746,48 @@ namespace BlackSimPlugin CLogMessage(this).warning(this->getInvalidSituationLogMessage(callsign, result.getInterpolationStatus())); } - this->updateRemoteAircraftParts(xplaneAircraft, result); + const CAircraftParts parts(result); + if (result.getPartsStatus().isSupportingParts() || parts.getPartsDetails() == CAircraftParts::GuessedParts) + { + if(xplaneAircraft.getPartsAsSent() == parts) { continue; } + + surfaceCallsign.push_back(xplaneAircraft.getCallsign().asString()); + gear.push_back(parts.isGearDown() ? 1 : 0); + flap.push_back(parts.getFlapsPercent() / 100.0); + spoiler.push_back(parts.isSpoilersOut() ? 1 : 0); + speedBrake.push_back(parts.isSpoilersOut() ? 1 : 0); + slat.push_back(parts.getFlapsPercent() / 100.0); + wingSweep.push_back(0.0); + thrust.push_back(parts.isAnyEngineOn() ? 0 : 0.75); + elevator.push_back(0.0); + rudder.push_back(0.0); + aileron.push_back(0.0); + landLight.push_back(parts.getLights().isLandingOn()); + beaconLight.push_back(parts.getLights().isBeaconOn()); + strobeLight.push_back(parts.getLights().isStrobeOn()); + navLight.push_back(parts.getLights().isNavOn()); + lightPattern.push_back(0); + onGround.push_back(parts.isOnGround()); + } } // all callsigns + if (! posCallsigns.isEmpty()) + { + m_trafficProxy->setPlanePositions(posCallsigns, latitudes, longitudes, altitudes, pitches, rolles, headings); + } + + if (! surfaceCallsign.isEmpty()) + { + m_trafficProxy->setPlaneSurfaces(surfaceCallsign, gear, flap, spoiler, speedBrake, slat, wingSweep, thrust, elevator, rudder, aileron, landLight, beaconLight, strobeLight, navLight, lightPattern, onGround); + } + const qint64 dt = QDateTime::currentMSecsSinceEpoch() - currentTimestamp; m_statsUpdateAircraftTimeTotalMs += dt; m_statsUpdateAircraftCountMs++; m_statsUpdateAircraftTimeAvgMs = m_statsUpdateAircraftTimeTotalMs / m_statsUpdateAircraftCountMs; } - bool CSimulatorXPlane::updateRemoteAircraftParts(const CXPlaneMPAircraft &xplaneAircraft, const CInterpolationResult &result) - { - if (!result.getPartsStatus().isSupportingParts()) { return false; } - return this->sendRemoteAircraftPartsToSimulator(xplaneAircraft, result); - } - - bool CSimulatorXPlane::sendRemoteAircraftPartsToSimulator(const CXPlaneMPAircraft &xplaneAircraft, const CAircraftParts &parts) - { - // same as in simulator or same as already send to simulator? - if (xplaneAircraft.getPartsAsSent() == parts) { return true; } - - m_trafficProxy->setPlaneSurfaces(xplaneAircraft.getCallsign().asString(), - parts.isGearDown() ? 1 : 0, - parts.getFlapsPercent() / 100.0, - parts.isSpoilersOut() ? 1 : 0, - parts.isSpoilersOut() ? 1 : 0, - parts.getFlapsPercent() / 100.0, - 0, parts.isAnyEngineOn() ? 0 : 0.75, - 0, 0, 0, - parts.getLights().isLandingOn(), parts.getLights().isBeaconOn(), parts.getLights().isStrobeOn(), parts.getLights().isNavOn(), - 0, parts.isOnGround()); - return true; - } - void CSimulatorXPlane::requestRemoteAircraftDataFromXPlane() { if (!isConnected()) { return; } diff --git a/src/plugins/simulator/xplane/simulatorxplane.h b/src/plugins/simulator/xplane/simulatorxplane.h index 6cae3d144..9cbf1eda2 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.h +++ b/src/plugins/simulator/xplane/simulatorxplane.h @@ -177,12 +177,6 @@ namespace BlackSimPlugin //! \remark this is where the interpolated data are set void updateRemoteAircraft(); - //! Update remote aircraft parts (send to XSwiftBus) - bool updateRemoteAircraftParts(const CXPlaneMPAircraft &xplaneAircraft, const BlackMisc::Simulation::CInterpolationResult &result); - - //! Send parts to simulator - bool sendRemoteAircraftPartsToSimulator(const CXPlaneMPAircraft &xplaneAircraft, const BlackMisc::Aviation::CAircraftParts &parts); - void requestRemoteAircraftDataFromXPlane(); void updateRemoteAircraftFromSimulator(const QString &callsign, double latitudeDeg, double longitudeDeg, double elevationMeters, double modelVerticalOffsetMeters); void updateAirportsInRange(); diff --git a/src/plugins/simulator/xplane/xswiftbustrafficproxy.cpp b/src/plugins/simulator/xplane/xswiftbustrafficproxy.cpp index 00d578a1e..5220f5995 100644 --- a/src/plugins/simulator/xplane/xswiftbustrafficproxy.cpp +++ b/src/plugins/simulator/xplane/xswiftbustrafficproxy.cpp @@ -13,6 +13,10 @@ #define XSWIFTBUS_SERVICENAME "org.swift-project.xswiftbus" +using namespace BlackMisc::Aviation; +using namespace BlackMisc::Geo; +using namespace BlackMisc::PhysicalQuantities; + namespace BlackSimPlugin { namespace XPlane @@ -78,25 +82,16 @@ namespace BlackSimPlugin m_dbusInterface->callDBus(QLatin1String("removeAllPlanes")); } - void CXSwiftBusTrafficProxy::addPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading, qint64 relativeTime, qint64 timeOffset) + void CXSwiftBusTrafficProxy::setPlanePositions(const QStringList &callsigns, const QList &latitudes, const QList &longitudes, const QList &altitudes, + const QList &pitches, const QList &rolles, const QList &headings) { - m_dbusInterface->callDBus(QLatin1String("addPlanePosition"), callsign, latitude, longitude, altitude, pitch, roll, heading, relativeTime, timeOffset); + m_dbusInterface->callDBus(QLatin1String("setPlanePositions"), callsigns, latitudes, longitudes, altitudes, pitches, rolles, headings); } - void CXSwiftBusTrafficProxy::setPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading) - { - m_dbusInterface->callDBus(QLatin1String("setPlanePosition"), callsign, latitude, longitude, altitude, pitch, roll, heading); - } - - void CXSwiftBusTrafficProxy::addPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust, - double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround, qint64 relativeTime, qint64 timeOffset) - { - m_dbusInterface->callDBus(QLatin1String("addPlaneSurfaces"), callsign, gear, flap, spoiler, speedBrake, slat, wingSweep, thrust, elevator, rudder, aileron, - landLight, beaconLight, strobeLight, navLight, lightPattern, onGround, relativeTime, timeOffset); - } - - void CXSwiftBusTrafficProxy::setPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust, - double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround) + void CXSwiftBusTrafficProxy::setPlaneSurfaces(const QStringList &callsign, const QList &gear, const QList &flap, const QList &spoiler, + const QList &speedBrake, const QList &slat, const QList &wingSweep, const QList &thrust, + const QList &elevator, const QList &rudder, const QList &aileron, const QList &landLight, + const QList &beaconLight, const QList &strobeLight, const QList &navLight, const QList &lightPattern, const QList &onGround) { m_dbusInterface->callDBus(QLatin1String("setPlaneSurfaces"), callsign, gear, flap, spoiler, speedBrake, slat, wingSweep, thrust, elevator, rudder, aileron, landLight, beaconLight, strobeLight, navLight, lightPattern, onGround); @@ -116,5 +111,28 @@ namespace BlackSimPlugin { m_dbusInterface->callDBus(QLatin1String("requestRemoteAircraftData")); } + + void CXSwiftBusTrafficProxy::getEelevationAtPosition(const CCallsign &callsign, double latitude, double longitude, double altitude, + const ElevationCallback &setter) + { + std::function callback = [=](QDBusPendingCallWatcher * watcher) + { + QDBusPendingReply reply = *watcher; + if (!reply.isError()) + { + CCallsign cs(reply.argumentAt<0>()); + double elevationMeters = reply.argumentAt<1>(); + CAltitude elevationAlt(elevationMeters, CLengthUnit::m()); + elevationAlt.switchUnit(CLengthUnit::ft()); + CElevationPlane elevation(CLatitude(latitude, CAngleUnit::deg()), + CLongitude(longitude, CAngleUnit::deg()), + elevationAlt); + elevation.setSinglePointRadius(); + setter(elevation, cs); + } + watcher->deleteLater(); + }; + m_dbusInterface->callDBusAsync(QLatin1String("getEelevationAtPosition"), callback, callsign.asString(), latitude, longitude, altitude); + } } } diff --git a/src/plugins/simulator/xplane/xswiftbustrafficproxy.h b/src/plugins/simulator/xplane/xswiftbustrafficproxy.h index 067316dd8..12df0be8d 100644 --- a/src/plugins/simulator/xplane/xswiftbustrafficproxy.h +++ b/src/plugins/simulator/xplane/xswiftbustrafficproxy.h @@ -13,6 +13,8 @@ #define BLACKSIMPLUGIN_XSWIFTBUS_TRAFFIC_PROXY_H #include "blackmisc/genericdbusinterface.h" +#include "blackmisc/aviation/callsign.h" +#include "blackmisc/geo/elevationplane.h" #include #include @@ -37,6 +39,8 @@ namespace BlackSimPlugin Q_OBJECT public: + using ElevationCallback = std::function; + //! Service name static const QString &InterfaceName() { @@ -100,19 +104,15 @@ namespace BlackSimPlugin //! \copydoc XSwiftBus::CTraffic::removeAllPlanes void removeAllPlanes(); - //! \deprecated XSwiftBus::CTraffic::addPlanePosition - void addPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading, qint64 relativeTime, qint64 timeOffset); - - //! \copydoc XSwiftBus::CTraffic::setPlanePosition - void setPlanePosition(const QString &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading); - - //! \deprecated XSwiftBus::CTraffic::addPlaneSurfaces - void addPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust, - double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround, qint64 relativeTime, qint64 timeOffset); + //! \copydoc XSwiftBus::CTraffic::setPlanePositions + void setPlanePositions(const QStringList &callsigns, const QList &latitudes, const QList &longitudes, const QList &altitudes, + const QList &pitches, const QList &rolles, const QList &headings); //! \copydoc XSwiftBus::CTraffic::setPlaneSurfaces - void setPlaneSurfaces(const QString &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust, - double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround); + void setPlaneSurfaces(const QStringList &callsign, const QList &gear, const QList &flap, const QList &spoiler, + const QList &speedBrake, const QList &slat, const QList &wingSweep, const QList &thrust, + const QList &elevator, const QList &rudder, const QList &aileron, const QList &landLight, + const QList &beaconLight, const QList &strobeLight, const QList &navLight, const QList &lightPattern, const QList &onGround); //! \copydoc XSwiftBus::CTraffic::setPlaneTransponder void setPlaneTransponder(const QString &callsign, int code, bool modeC, bool ident); @@ -123,6 +123,10 @@ namespace BlackSimPlugin //! \copydoc XSwiftBus::CTraffic::requestRemoteAircraftData void requestRemoteAircraftData(); + //! \copydoc XSwiftBus::CTraffic::getEelevationAtPosition + void getEelevationAtPosition(const BlackMisc::Aviation::CCallsign &callsign, double latitude, double longitude, double altitude, + const ElevationCallback &setter); + private: BlackMisc::CGenericDBusInterface *m_dbusInterface = nullptr; }; diff --git a/src/xswiftbus/dbusmessage.cpp b/src/xswiftbus/dbusmessage.cpp index b5c817ba1..d31f6fc83 100644 --- a/src/xswiftbus/dbusmessage.cpp +++ b/src/xswiftbus/dbusmessage.cpp @@ -171,6 +171,68 @@ namespace XSwiftBus value = std::string(str); } + void CDBusMessage::getArgument(std::vector &value) + { + DBusMessageIter arrayIterator; + dbus_message_iter_recurse(&m_messageIterator, &arrayIterator); + do + { + if (dbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_INT32) { return; } + dbus_int32_t i; + dbus_message_iter_get_basic(&arrayIterator, &i); + value.push_back(i); + } + while (dbus_message_iter_next(&arrayIterator)); + dbus_message_iter_next(&m_messageIterator); + } + + void CDBusMessage::getArgument(std::vector &value) + { + if (dbus_message_iter_get_arg_type(&m_messageIterator) != DBUS_TYPE_ARRAY) { return; } + DBusMessageIter arrayIterator; + dbus_message_iter_recurse(&m_messageIterator, &arrayIterator); + do + { + if (dbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_BOOLEAN) { return; } + dbus_bool_t b; + dbus_message_iter_get_basic(&arrayIterator, &b); + bool v = b == TRUE ? true : false; + value.push_back(v); + } + while (dbus_message_iter_next(&arrayIterator)); + dbus_message_iter_next(&m_messageIterator); + } + + void CDBusMessage::getArgument(std::vector &value) + { + DBusMessageIter arrayIterator; + dbus_message_iter_recurse(&m_messageIterator, &arrayIterator); + do + { + if (dbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_DOUBLE) { return; } + double d; + dbus_message_iter_get_basic(&arrayIterator, &d); + value.push_back(d); + } + while (dbus_message_iter_next(&arrayIterator)); + dbus_message_iter_next(&m_messageIterator); + } + + void CDBusMessage::getArgument(std::vector &value) + { + DBusMessageIter arrayIterator; + dbus_message_iter_recurse(&m_messageIterator, &arrayIterator); + do + { + if (dbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_STRING) { return; } + const char *str = nullptr; + dbus_message_iter_get_basic(&arrayIterator, &str); + value.push_back(std::string(str)); + } + while (dbus_message_iter_next(&arrayIterator)); + dbus_message_iter_next(&m_messageIterator); + } + CDBusMessage CDBusMessage::createSignal(const std::string &path, const std::string &interfaceName, const std::string &signalName) { DBusMessage *signal = dbus_message_new_signal(path.c_str(), interfaceName.c_str(), signalName.c_str()); diff --git a/src/xswiftbus/dbusmessage.h b/src/xswiftbus/dbusmessage.h index b6b5fd2d2..3779007ff 100644 --- a/src/xswiftbus/dbusmessage.h +++ b/src/xswiftbus/dbusmessage.h @@ -77,6 +77,10 @@ namespace XSwiftBus void getArgument(bool &value); void getArgument(double &value); void getArgument(std::string &value); + void getArgument(std::vector &value); + void getArgument(std::vector &value); + void getArgument(std::vector &value); + void getArgument(std::vector &value); //! @} //! Creates a DBus message containing a DBus signal diff --git a/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml b/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml index 4a3ff2008..aea134bf6 100644 --- a/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml +++ b/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml @@ -46,23 +46,23 @@ R"( - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -72,5 +72,13 @@ R"( + + + + + + + + )" diff --git a/src/xswiftbus/traffic.cpp b/src/xswiftbus/traffic.cpp index ba648c940..67abc5ff1 100644 --- a/src/xswiftbus/traffic.cpp +++ b/src/xswiftbus/traffic.cpp @@ -47,10 +47,12 @@ namespace XSwiftBus CDBusObject(dbusConnection) { registerDBusObjectPath(XSWIFTBUS_TRAFFIC_INTERFACENAME, XSWIFTBUS_TRAFFIC_OBJECTPATH); + XPLMRegisterDrawCallback(drawCallback, xplm_Phase_Airplanes, 1, this); } CTraffic::~CTraffic() { + XPLMUnregisterDrawCallback(drawCallback, xplm_Phase_Airplanes, 1, this); cleanup(); } @@ -106,7 +108,8 @@ namespace XSwiftBus void CTraffic::emitSimFrame() { - sendDBusSignal("simFrame"); + if (m_emitSimFrame) { sendDBusSignal("simFrame"); } + m_emitSimFrame = !m_emitSimFrame; } void CTraffic::emitRemoteAircraftData(const std::string &callsign, double latitude, double longitude, double elevation, double modelVerticalOffset) @@ -256,47 +259,57 @@ namespace XSwiftBus m_planeViewMenuItems.clear(); } - void CTraffic::setPlanePosition(const std::string &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading) + void CTraffic::setPlanePositions(const std::vector &callsigns, std::vector latitudes, std::vector longitudes, std::vector altitudes, + std::vector pitches, std::vector rolles, std::vector headings) { - auto planeIt = m_planesByCallsign.find(callsign); - if (planeIt == m_planesByCallsign.end()) { return; } + for (size_t i = 0; i < callsigns.size(); i++) + { + auto planeIt = m_planesByCallsign.find(callsigns.at(i)); + if (planeIt == m_planesByCallsign.end()) { return; } - Plane *plane = planeIt->second; - if (!plane) { return; } - plane->position.lat = latitude; - plane->position.lon = longitude; - plane->position.elevation = altitude; - plane->position.pitch = static_cast(pitch); - plane->position.roll = static_cast(roll); - plane->position.heading = static_cast(heading); + Plane *plane = planeIt->second; + if (!plane) { return; } + plane->position.lat = latitudes.at(i); + plane->position.lon = longitudes.at(i); + plane->position.elevation = altitudes.at(i); + plane->position.pitch = static_cast(pitches.at(i)); + plane->position.roll = static_cast(rolles.at(i)); + plane->position.heading = static_cast(headings.at(i)); + } } - void CTraffic::setPlaneSurfaces(const std::string &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust, - double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround) + void CTraffic::setPlaneSurfaces(const std::vector &callsign, const std::vector &gear, const std::vector &flap, const std::vector &spoiler, + const std::vector &speedBrake, const std::vector &slat, const std::vector &wingSweep, const std::vector &thrust, + const std::vector &elevator, const std::vector &rudder, const std::vector &aileron, const std::vector &landLight, + const std::vector &beaconLight, const std::vector &strobeLight, const std::vector &navLight, const std::vector &lightPattern, const std::vector &onGround) { - (void) onGround; - auto planeIt = m_planesByCallsign.find(callsign); - if (planeIt == m_planesByCallsign.end()) { return; } + (void)onGround; - Plane *plane = planeIt->second; - if (!plane) { return; } + for (size_t i = 0; i < callsign.size(); i++) + { + auto planeIt = m_planesByCallsign.find(callsign.at(i)); + if (planeIt == m_planesByCallsign.end()) { return; } - plane->hasSurfaces = true; - plane->targetGearPosition = static_cast(gear); - plane->surfaces.flapRatio = static_cast(flap); - plane->surfaces.spoilerRatio = static_cast(spoiler); - plane->surfaces.speedBrakeRatio = static_cast(speedBrake); - plane->surfaces.slatRatio = static_cast(slat); - plane->surfaces.wingSweep = static_cast(wingSweep); - plane->surfaces.thrust = static_cast(thrust); - plane->surfaces.yokePitch = static_cast(elevator); - plane->surfaces.yokeHeading = static_cast(rudder); - plane->surfaces.yokeRoll = static_cast(aileron); - plane->surfaces.lights.landLights = landLight; - plane->surfaces.lights.bcnLights = beaconLight; - plane->surfaces.lights.strbLights = strobeLight; - plane->surfaces.lights.navLights = navLight; - plane->surfaces.lights.flashPattern = lightPattern; + Plane *plane = planeIt->second; + if (!plane) { return; } + + plane->hasSurfaces = true; + plane->targetGearPosition = static_cast(gear.at(i)); + plane->surfaces.flapRatio = static_cast(flap.at(i)); + plane->surfaces.spoilerRatio = static_cast(spoiler.at(i)); + plane->surfaces.speedBrakeRatio = static_cast(speedBrake.at(i)); + plane->surfaces.slatRatio = static_cast(slat.at(i)); + plane->surfaces.wingSweep = static_cast(wingSweep.at(i)); + plane->surfaces.thrust = static_cast(thrust.at(i)); + plane->surfaces.yokePitch = static_cast(elevator.at(i)); + plane->surfaces.yokeHeading = static_cast(rudder.at(i)); + plane->surfaces.yokeRoll = static_cast(aileron.at(i)); + plane->surfaces.lights.landLights = landLight.at(i); + plane->surfaces.lights.bcnLights = beaconLight.at(i); + plane->surfaces.lights.strbLights = strobeLight.at(i); + plane->surfaces.lights.navLights = navLight.at(i); + plane->surfaces.lights.flashPattern = lightPattern.at(i); + } } void CTraffic::setPlaneTransponder(const std::string &callsign, int code, bool modeC, bool ident) @@ -326,11 +339,26 @@ namespace XSwiftBus double groundElevation = plane->terrainProbe.getElevation(lat, lon, elevation); if (std::isnan(groundElevation)) { groundElevation = 0.0; } double fudgeFactor = 3.0; - actualVertOffsetInfo(plane->modelName.c_str(), nullptr, &fudgeFactor); + XPMPGetVerticalOffset(plane->id, &fudgeFactor); + // actualVertOffsetInfo(plane->modelName.c_str(), nullptr, &fudgeFactor); emitRemoteAircraftData(plane->callsign, lat, lon, groundElevation, fudgeFactor); } } + double CTraffic::getEelevationAtPosition(const std::string &callsign, double latitude, double longitude, double altitude) + { + auto planeIt = m_planesByCallsign.find(callsign); + if (planeIt != m_planesByCallsign.end()) + { + Plane *plane = planeIt->second; + return plane->terrainProbe.getElevation(latitude, longitude, altitude); + } + else + { + return m_terrainProbe.getElevation(latitude, longitude, altitude); + } + } + const char *introspection_traffic = DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE #include "org.swift_project.xswiftbus.traffic.xml" @@ -465,49 +493,49 @@ namespace XSwiftBus removeAllPlanes(); }); } - else if (message.getMethodName() == "setPlanePosition") + else if (message.getMethodName() == "setPlanePositions") { maybeSendEmptyDBusReply(wantsReply, sender, serial); - std::string callsign; - double latitude = 0.0; - double longitude = 0.0; - double altitude = 0.0; - double pitch = 0.0; - double roll = 0.0; - double heading = 0.0; + std::vector callsigns; + std::vector latitudes; + std::vector longitudes; + std::vector altitudes; + std::vector pitches; + std::vector rolles; + std::vector headings; message.beginArgumentRead(); - message.getArgument(callsign); - message.getArgument(latitude); - message.getArgument(longitude); - message.getArgument(altitude); - message.getArgument(pitch); - message.getArgument(roll); - message.getArgument(heading); + message.getArgument(callsigns); + message.getArgument(latitudes); + message.getArgument(longitudes); + message.getArgument(altitudes); + message.getArgument(pitches); + message.getArgument(rolles); + message.getArgument(headings); queueDBusCall([ = ]() { - setPlanePosition(callsign, latitude, longitude, altitude, pitch, roll, heading); + setPlanePositions(callsigns, latitudes, longitudes, altitudes, pitches, rolles, headings); }); } else if (message.getMethodName() == "setPlaneSurfaces") { maybeSendEmptyDBusReply(wantsReply, sender, serial); - std::string callsign; - double gear = 0.0; - double flap = 0.0; - double spoiler = 0.0; - double speedBrake = 0.0; - double slat = 0.0; - double wingSweep = 0.0; - double thrust = 0.0; - double elevator = 0.0; - double rudder = 0.0; - double aileron = 0.0; - bool landLight = false; - bool beaconLight = false; - bool strobeLight = false; - bool navLight = false; - bool lightPattern = false; - bool onGround = false; + std::vector callsign; + std::vector gear; + std::vector flap; + std::vector spoiler; + std::vector speedBrake; + std::vector slat; + std::vector wingSweep; + std::vector thrust; + std::vector elevator; + std::vector rudder; + std::vector aileron; + std::vector landLight; + std::vector beaconLight; + std::vector strobeLight; + std::vector navLight; + std::vector lightPattern; + std::vector onGround; message.beginArgumentRead(); message.getArgument(callsign); message.getArgument(gear); @@ -558,6 +586,26 @@ namespace XSwiftBus requestRemoteAircraftData(); }); } + else if (message.getMethodName() == "getEelevationAtPosition") + { + std::string callsign; + double latitude; + double longitude; + double altitude; + message.beginArgumentRead(); + message.getArgument(callsign); + message.getArgument(latitude); + message.getArgument(longitude); + message.getArgument(altitude); + queueDBusCall([ = ]() + { + CDBusMessage reply = CDBusMessage::createReply(sender, serial); + reply.beginArgumentWrite(); + reply.appendArgument(callsign); + reply.appendArgument(getEelevationAtPosition(callsign, latitude, longitude, altitude)); + ; sendDBusMessage(reply); + }); + } else { // Unknown message. Tell DBus that we cannot handle it @@ -569,7 +617,6 @@ namespace XSwiftBus int CTraffic::processDBus() { - emitSimFrame(); invokeQueuedDBusCalls(); return 1; } @@ -699,6 +746,21 @@ namespace XSwiftBus // Return 1 to indicate we want to keep controlling the camera. return 1; } + + int CTraffic::drawCallback(XPLMDrawingPhase phase, int isBefore, void *refcon) + { + (void)phase; + (void)isBefore; + CTraffic *traffic = static_cast(refcon); + + // The draw callback is called several times per frame. We need this only once. + if (traffic->m_worldRenderType.get() == 0) + { + traffic->emitSimFrame(); + } + + return 1; + } } //! \endcond diff --git a/src/xswiftbus/traffic.h b/src/xswiftbus/traffic.h index 62a5f85e4..bbf4a8847 100644 --- a/src/xswiftbus/traffic.h +++ b/src/xswiftbus/traffic.h @@ -94,12 +94,15 @@ namespace XSwiftBus //! Remove all traffic aircraft void removeAllPlanes(); - //! Set the position of a traffic aircraft - void setPlanePosition(const std::string &callsign, double latitude, double longitude, double altitude, double pitch, double roll, double heading); + //! Set the position of multiple traffic aircrafts + void setPlanePositions(const std::vector &callsigns, std::vector latitudes, std::vector longitudes, std::vector altitude, + std::vector pitchs, std::vector rolls, std::vector headings); - //! Set the flight control surfaces and lights of a traffic aircraft - void setPlaneSurfaces(const std::string &callsign, double gear, double flap, double spoiler, double speedBrake, double slat, double wingSweep, double thrust, - double elevator, double rudder, double aileron, bool landLight, bool beaconLight, bool strobeLight, bool navLight, int lightPattern, bool onGround); + //! Set the flight control surfaces and lights of multiple traffic aircrafts + void setPlaneSurfaces(const std::vector &callsign, const std::vector &gear, const std::vector &flap, const std::vector &spoiler, + const std::vector &speedBrake, const std::vector &slat, const std::vector &wingSweep, const std::vector &thrust, + const std::vector &elevator, const std::vector &rudder, const std::vector &aileron, const std::vector &landLight, + const std::vector &beaconLight, const std::vector &strobeLight, const std::vector &navLight, const std::vector &lightPattern, const std::vector &onGround); //! Set the transponder of a traffic aircraft void setPlaneTransponder(const std::string &callsign, int code, bool modeC, bool ident); @@ -107,14 +110,18 @@ namespace XSwiftBus //! Request traffic plane data. A signal remoteAircraftData will be emitted for each known plane void requestRemoteAircraftData(); + //! Get the ground elevation at an arbitrary position + double getEelevationAtPosition(const std::string &callsign, double latitude, double longitude, double altitude); + int processDBus() override; protected: - DBusHandlerResult dbusMessageHandler(const CDBusMessage &message) override; + DBusHandlerResult dbusMessageHandler(const CDBusMessage &message) override; private: bool m_initialized = false; bool m_enabled = false; + CTerrainProbe m_terrainProbe; void emitSimFrame(); void emitRemoteAircraftData(const std::string &callsign, double latitude, double longitude, double elevation, double modelVerticalOffset); @@ -123,6 +130,7 @@ namespace XSwiftBus static int preferences(const char *section, const char *name, int def); static float preferences(const char *section, const char *name, float def); static int orbitPlaneFunc(XPLMCameraPosition_t *cameraPosition, int isLosingControl, void *refcon); + static int drawCallback(XPLMDrawingPhase phase, int isBefore, void *refcon); struct Plane { @@ -153,6 +161,9 @@ namespace XSwiftBus std::unordered_map m_planeViewMenuItems; std::string m_planeViewCallsign; + DataRef m_worldRenderType; + bool m_emitSimFrame = true; + int getPlaneData(void *id, int dataType, void *io_data); static int getPlaneData(void *id, int dataType, void *io_data, void *self) {