Group sending of all plane positions and surfaces into a single DBus call

This commit is contained in:
Roland Winklmeier
2018-04-14 20:25:54 +02:00
parent 3ef18a788a
commit 848da69fe1
9 changed files with 374 additions and 160 deletions

View File

@@ -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<CXPlaneMPAircraft> xplaneAircraftList(m_xplaneAircraftObjects.values());
QStringList posCallsigns;
QList<double> latitudes;
QList<double> longitudes;
QList<double> altitudes;
QList<double> pitches;
QList<double> rolles;
QList<double> headings;
QStringList surfaceCallsign;
QList<double> gear;
QList<double> flap;
QList<double> spoiler;
QList<double> speedBrake;
QList<double> slat;
QList<double> wingSweep;
QList<double> thrust;
QList<double> elevator;
QList<double> rudder;
QList<double> aileron;
QList<bool> landLight;
QList<bool> beaconLight;
QList<bool> strobeLight;
QList<bool> navLight;
QList<int> lightPattern;
QList<bool> 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; }

View File

@@ -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();

View File

@@ -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<double> &latitudes, const QList<double> &longitudes, const QList<double> &altitudes,
const QList<double> &pitches, const QList<double> &rolles, const QList<double> &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<double> &gear, const QList<double> &flap, const QList<double> &spoiler,
const QList<double> &speedBrake, const QList<double> &slat, const QList<double> &wingSweep, const QList<double> &thrust,
const QList<double> &elevator, const QList<double> &rudder, const QList<double> &aileron, const QList<bool> &landLight,
const QList<bool> &beaconLight, const QList<bool> &strobeLight, const QList<bool> &navLight, const QList<int> &lightPattern, const QList<bool> &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<void(QDBusPendingCallWatcher *)> callback = [=](QDBusPendingCallWatcher * watcher)
{
QDBusPendingReply<QString, double> 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);
}
}
}

View File

@@ -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 <QObject>
#include <QString>
@@ -37,6 +39,8 @@ namespace BlackSimPlugin
Q_OBJECT
public:
using ElevationCallback = std::function<void (const BlackMisc::Geo::CElevationPlane &, const BlackMisc::Aviation::CCallsign &)>;
//! 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<double> &latitudes, const QList<double> &longitudes, const QList<double> &altitudes,
const QList<double> &pitches, const QList<double> &rolles, const QList<double> &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<double> &gear, const QList<double> &flap, const QList<double> &spoiler,
const QList<double> &speedBrake, const QList<double> &slat, const QList<double> &wingSweep, const QList<double> &thrust,
const QList<double> &elevator, const QList<double> &rudder, const QList<double> &aileron, const QList<bool> &landLight,
const QList<bool> &beaconLight, const QList<bool> &strobeLight, const QList<bool> &navLight, const QList<int> &lightPattern, const QList<bool> &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;
};

View File

@@ -171,6 +171,68 @@ namespace XSwiftBus
value = std::string(str);
}
void CDBusMessage::getArgument(std::vector<int> &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<bool> &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<double> &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<std::string> &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());

View File

@@ -77,6 +77,10 @@ namespace XSwiftBus
void getArgument(bool &value);
void getArgument(double &value);
void getArgument(std::string &value);
void getArgument(std::vector<int> &value);
void getArgument(std::vector<bool> &value);
void getArgument(std::vector<double> &value);
void getArgument(std::vector<std::string> &value);
//! @}
//! Creates a DBus message containing a DBus signal

View File

@@ -46,23 +46,23 @@ R"(<node>
<arg name="heading" type="d" direction="in"/>
</method>
<method name="setPlaneSurfaces">
<arg name="callsign" type="s" direction="in"/>
<arg name="gear" type="d" direction="in"/>
<arg name="flap" type="d" direction="in"/>
<arg name="spoiler" type="d" direction="in"/>
<arg name="speedBrake" type="d" direction="in"/>
<arg name="slat" type="d" direction="in"/>
<arg name="wingSweep" type="d" direction="in"/>
<arg name="thrust" type="d" direction="in"/>
<arg name="elevator" type="d" direction="in"/>
<arg name="rudder" type="d" direction="in"/>
<arg name="aileron" type="d" direction="in"/>
<arg name="landLight" type="b" direction="in"/>
<arg name="beaconLight" type="b" direction="in"/>
<arg name="strobeLight" type="b" direction="in"/>
<arg name="navLight" type="b" direction="in"/>
<arg name="lightPattern" type="i" direction="in"/>
<arg name="onGround" type="b" direction="in"/>
<arg name="callsign" type="as" direction="in"/>
<arg name="gear" type="ad" direction="in"/>
<arg name="flap" type="ad" direction="in"/>
<arg name="spoiler" type="ad" direction="in"/>
<arg name="speedBrake" type="ad" direction="in"/>
<arg name="slat" type="ad" direction="in"/>
<arg name="wingSweep" type="ad" direction="in"/>
<arg name="thrust" type="ad" direction="in"/>
<arg name="elevator" type="ad" direction="in"/>
<arg name="rudder" type="ad" direction="in"/>
<arg name="aileron" type="ad" direction="in"/>
<arg name="landLight" type="ab" direction="in"/>
<arg name="beaconLight" type="ab" direction="in"/>
<arg name="strobeLight" type="ab" direction="in"/>
<arg name="navLight" type="ab" direction="in"/>
<arg name="lightPattern" type="ai" direction="in"/>
<arg name="onGround" type="ab" direction="in"/>
</method>
<method name="setPlaneTransponder">
<arg name="callsign" type="s" direction="in"/>
@@ -72,5 +72,13 @@ R"(<node>
</method>
<method name="requestRemoteAircraftData">
</method>
<method name="getEelevationAtPosition">
<arg name="callsign" type="s" direction="in"/>
<arg name="latitude" type="d" direction="in"/>
<arg name="longitude" type="d" direction="in"/>
<arg name="altitude" type="d" direction="in"/>
<arg type="s" direction="out"/>
<arg type="d" direction="out"/>
</method>
</interface>
</node>)"

View File

@@ -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<std::string> &callsigns, std::vector<double> latitudes, std::vector<double> longitudes, std::vector<double> altitudes,
std::vector<double> pitches, std::vector<double> rolles, std::vector<double> 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<float>(pitch);
plane->position.roll = static_cast<float>(roll);
plane->position.heading = static_cast<float>(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<float>(pitches.at(i));
plane->position.roll = static_cast<float>(rolles.at(i));
plane->position.heading = static_cast<float>(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<std::string> &callsign, const std::vector<double> &gear, const std::vector<double> &flap, const std::vector<double> &spoiler,
const std::vector<double> &speedBrake, const std::vector<double> &slat, const std::vector<double> &wingSweep, const std::vector<double> &thrust,
const std::vector<double> &elevator, const std::vector<double> &rudder, const std::vector<double> &aileron, const std::vector<bool> &landLight,
const std::vector<bool> &beaconLight, const std::vector<bool> &strobeLight, const std::vector<bool> &navLight, const std::vector<int> &lightPattern, const std::vector<bool> &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<float>(gear);
plane->surfaces.flapRatio = static_cast<float>(flap);
plane->surfaces.spoilerRatio = static_cast<float>(spoiler);
plane->surfaces.speedBrakeRatio = static_cast<float>(speedBrake);
plane->surfaces.slatRatio = static_cast<float>(slat);
plane->surfaces.wingSweep = static_cast<float>(wingSweep);
plane->surfaces.thrust = static_cast<float>(thrust);
plane->surfaces.yokePitch = static_cast<float>(elevator);
plane->surfaces.yokeHeading = static_cast<float>(rudder);
plane->surfaces.yokeRoll = static_cast<float>(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<float>(gear.at(i));
plane->surfaces.flapRatio = static_cast<float>(flap.at(i));
plane->surfaces.spoilerRatio = static_cast<float>(spoiler.at(i));
plane->surfaces.speedBrakeRatio = static_cast<float>(speedBrake.at(i));
plane->surfaces.slatRatio = static_cast<float>(slat.at(i));
plane->surfaces.wingSweep = static_cast<float>(wingSweep.at(i));
plane->surfaces.thrust = static_cast<float>(thrust.at(i));
plane->surfaces.yokePitch = static_cast<float>(elevator.at(i));
plane->surfaces.yokeHeading = static_cast<float>(rudder.at(i));
plane->surfaces.yokeRoll = static_cast<float>(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<std::string> callsigns;
std::vector<double> latitudes;
std::vector<double> longitudes;
std::vector<double> altitudes;
std::vector<double> pitches;
std::vector<double> rolles;
std::vector<double> 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<std::string> callsign;
std::vector<double> gear;
std::vector<double> flap;
std::vector<double> spoiler;
std::vector<double> speedBrake;
std::vector<double> slat;
std::vector<double> wingSweep;
std::vector<double> thrust;
std::vector<double> elevator;
std::vector<double> rudder;
std::vector<double> aileron;
std::vector<bool> landLight;
std::vector<bool> beaconLight;
std::vector<bool> strobeLight;
std::vector<bool> navLight;
std::vector<int> lightPattern;
std::vector<bool> 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<CTraffic *>(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

View File

@@ -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<std::string> &callsigns, std::vector<double> latitudes, std::vector<double> longitudes, std::vector<double> altitude,
std::vector<double> pitchs, std::vector<double> rolls, std::vector<double> 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<std::string> &callsign, const std::vector<double> &gear, const std::vector<double> &flap, const std::vector<double> &spoiler,
const std::vector<double> &speedBrake, const std::vector<double> &slat, const std::vector<double> &wingSweep, const std::vector<double> &thrust,
const std::vector<double> &elevator, const std::vector<double> &rudder, const std::vector<double> &aileron, const std::vector<bool> &landLight,
const std::vector<bool> &beaconLight, const std::vector<bool> &strobeLight, const std::vector<bool> &navLight, const std::vector<int> &lightPattern, const std::vector<bool> &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<std::string, CMenuItem> m_planeViewMenuItems;
std::string m_planeViewCallsign;
DataRef<xplane::data::sim::graphics::view::world_render_type> 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)
{