Ref T778 XSwiftBus traffic service prodives water/land flag for elevations

This commit is contained in:
Mat Sutcliffe
2020-04-08 22:22:12 +01:00
parent 7c4fe83799
commit 22ebf6c5ea
16 changed files with 52 additions and 34 deletions

View File

@@ -360,7 +360,7 @@ namespace BlackCore
return false;
}
void ISimulator::callbackReceivedRequestedElevation(const CElevationPlane &plane, const CCallsign &callsign)
void ISimulator::callbackReceivedRequestedElevation(const CElevationPlane &plane, const CCallsign &callsign, bool isWater)
{
if (this->isShuttingDown()) { return; }
if (plane.isNull()) { return; } // this happens if requested for a coordinate where scenery is not available
@@ -377,6 +377,7 @@ namespace BlackCore
// signal we have received the elevation
// used by log display
emit this->receivedRequestedElevation(plane, callsign);
Q_UNUSED(isWater)
}
void ISimulator::resetAircraftStatistics()

View File

@@ -268,7 +268,7 @@ namespace BlackCore
//! A requested elevation has been received
//! \remark public for testing purposes
virtual void callbackReceivedRequestedElevation(const BlackMisc::Geo::CElevationPlane &plane, const BlackMisc::Aviation::CCallsign &callsign);
virtual void callbackReceivedRequestedElevation(const BlackMisc::Geo::CElevationPlane &plane, const BlackMisc::Aviation::CCallsign &callsign, bool isWater);
//! Allows to print out simulator specific statistics
virtual QString getStatisticsSimulatorSpecific() const { return QString(); }

View File

@@ -429,7 +429,7 @@ namespace BlackGui
const CElevationPlane ep(situations.latestAdjustedObject(), alt, CElevationPlane::singlePointRadius());
// inject as received from simulator
m_simulator->callbackReceivedRequestedElevation(ep, m_callsign);
m_simulator->callbackReceivedRequestedElevation(ep, m_callsign, false);
}
void CInterpolationLogDisplay::onElevationHistoryCountFinished()

View File

@@ -245,7 +245,7 @@ namespace BlackSimPlugin
if (!myself) { return; }
// updates in providers and emits signal
ISimulator::callbackReceivedRequestedElevation(elv, callsign);
ISimulator::callbackReceivedRequestedElevation(elv, callsign, false);
});
emit this->requestedElevation(callsign);

View File

@@ -849,7 +849,7 @@ namespace BlackSimPlugin
}
using namespace std::placeholders;
auto callback = std::bind(&CSimulatorFlightgear::callbackReceivedRequestedElevation, this, _1, _2);
auto callback = std::bind(&CSimulatorFlightgear::callbackReceivedRequestedElevation, this, _1, _2, false);
// Request
m_trafficProxy->getElevationAtPosition(callsign,

View File

@@ -897,7 +897,7 @@ namespace BlackSimPlugin
void CSimulatorFsxCommon::updateProbeFromSimulator(const CCallsign &callsign, const DataDefinitionPosData &remoteAircraftData)
{
const CElevationPlane elevation(remoteAircraftData.latitudeDeg, remoteAircraftData.longitudeDeg, remoteAircraftData.elevationFt, CElevationPlane::singlePointRadius());
this->callbackReceivedRequestedElevation(elevation, callsign);
this->callbackReceivedRequestedElevation(elevation, callsign, false);
}
void CSimulatorFsxCommon::updateOwnAircraftFromSimulator(const DataDefinitionClientAreaSb &sbDataArea)

View File

@@ -92,7 +92,7 @@ namespace BlackSimPlugin
const CElevationPlane ep(coordinate, CElevationPlane::singlePointRadius());
const CCallsign cs(simulatorP3D->getCallsignForPendingProbeRequests(requestId, true));
simulatorP3D->callbackReceivedRequestedElevation(ep, cs);
simulatorP3D->callbackReceivedRequestedElevation(ep, cs, false);
}
break;
default:

View File

@@ -213,7 +213,7 @@ namespace BlackSimPlugin
return true;
}
void CSimulatorXPlane::callbackReceivedRequestedElevation(const CElevationPlane &plane, const CCallsign &callsign)
void CSimulatorXPlane::callbackReceivedRequestedElevation(const CElevationPlane &plane, const CCallsign &callsign, bool isWater)
{
static const QString hint("probe callback");
if (!this->handleProbeValue(plane, callsign, hint, false))
@@ -221,7 +221,7 @@ namespace BlackSimPlugin
this->removePendingElevationRequest(callsign);
return;
}
CSimulatorPluginCommon::callbackReceivedRequestedElevation(plane, callsign);
CSimulatorPluginCommon::callbackReceivedRequestedElevation(plane, callsign, isWater);
}
bool CSimulatorXPlane::isSuspiciousTerrainValue(const CElevationPlane &elevation)
@@ -273,7 +273,7 @@ namespace BlackSimPlugin
}
using namespace std::placeholders;
auto callback = std::bind(&CSimulatorXPlane::callbackReceivedRequestedElevation, this, _1, _2);
auto callback = std::bind(&CSimulatorXPlane::callbackReceivedRequestedElevation, this, _1, _2, _3);
// Request
m_trafficProxy->getElevationAtPosition(callsign,
@@ -1088,10 +1088,10 @@ namespace BlackSimPlugin
if (!m_trafficProxy || this->isShuttingDown()) { return; }
const QStringList csStrings = callsigns.getCallsignStrings();
QPointer<CSimulatorXPlane> myself(this);
m_trafficProxy->getRemoteAircraftData(csStrings, [ = ](const QStringList & callsigns, const QDoubleList & latitudesDeg, const QDoubleList & longitudesDeg, const QDoubleList & elevationsMeters, const QDoubleList & verticalOffsetsMeters)
m_trafficProxy->getRemoteAircraftData(csStrings, [ = ](const QStringList & callsigns, const QDoubleList & latitudesDeg, const QDoubleList & longitudesDeg, const QDoubleList & elevationsMeters, const QBoolList &waterFlags, const QDoubleList & verticalOffsetsMeters)
{
if (!myself) { return; }
this->updateRemoteAircraftFromSimulator(callsigns, latitudesDeg, longitudesDeg, elevationsMeters, verticalOffsetsMeters);
this->updateRemoteAircraftFromSimulator(callsigns, latitudesDeg, longitudesDeg, elevationsMeters, waterFlags, verticalOffsetsMeters);
});
}
@@ -1108,7 +1108,7 @@ namespace BlackSimPlugin
void CSimulatorXPlane::updateRemoteAircraftFromSimulator(
const QStringList &callsigns, const QDoubleList &latitudesDeg, const QDoubleList &longitudesDeg,
const QDoubleList &elevationsMeters, const QDoubleList &verticalOffsetsMeters)
const QDoubleList &elevationsMeters, const QBoolList &waterFlags, const QDoubleList &verticalOffsetsMeters)
{
const int size = callsigns.size();
@@ -1116,6 +1116,7 @@ namespace BlackSimPlugin
if (CBuildConfig::isLocalDeveloperDebugBuild())
{
Q_ASSERT_X(elevationsMeters.size() == size, Q_FUNC_INFO, "Wrong elevations");
Q_ASSERT_X(waterFlags.size() == size, Q_FUNC_INFO, "Wrong waterFlags");
Q_ASSERT_X(latitudesDeg.size() == size, Q_FUNC_INFO, "Wrong latitudesDeg");
Q_ASSERT_X(longitudesDeg.size() == size, Q_FUNC_INFO, "Wrong longitudesDeg");
Q_ASSERT_X(verticalOffsetsMeters.size() == size, Q_FUNC_INFO, "Wrong CG");
@@ -1152,6 +1153,7 @@ namespace BlackSimPlugin
// with T778 we do NOT use this function for elevation here if "isSuspicious"
const bool useElevation = this->handleProbeValue(elevation, cs, hint, true);
this->rememberElevationAndSimulatorCG(cs, xpAircraft.getAircraftModel(), false, useElevation ? elevation : CElevationPlane::null(), cg);
Q_UNUSED(waterFlags)
// loopback
if (logCallsigns.contains(cs))

View File

@@ -144,7 +144,7 @@ namespace BlackSimPlugin
virtual void resetAircraftStatistics() override;
virtual BlackMisc::CStatusMessageList getInterpolationMessages(const BlackMisc::Aviation::CCallsign &callsign) const override;
virtual bool testSendSituationAndParts(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftSituation &situation, const BlackMisc::Aviation::CAircraftParts &parts) override;
virtual void callbackReceivedRequestedElevation(const BlackMisc::Geo::CElevationPlane &plane, const BlackMisc::Aviation::CCallsign &callsign) override;
virtual void callbackReceivedRequestedElevation(const BlackMisc::Geo::CElevationPlane &plane, const BlackMisc::Aviation::CCallsign &callsign, bool isWater) override;
//! @}
//! \copydoc BlackMisc::Simulation::ISimulationEnvironmentProvider::requestElevation
@@ -178,6 +178,7 @@ namespace BlackSimPlugin
};
using QDoubleList = QList<double>;
using QBoolList = QList<bool>;
void setAirportsInRange(const QStringList &icaoCodes, const QStringList &names, const BlackMisc::CSequence<double> &lats, const BlackMisc::CSequence<double> &lons, const BlackMisc::CSequence<double> &alts);
void emitOwnAircraftModelChanged(const QString &path, const QString &filename, const QString &livery, const QString &icao,
@@ -222,7 +223,7 @@ namespace BlackSimPlugin
void onRemoteAircraftAdded(const QString &callsign);
void onRemoteAircraftAddingFailed(const QString &callsign);
void updateRemoteAircraftFromSimulator(const QStringList &callsigns, const QDoubleList &latitudesDeg, const QDoubleList &longitudesDeg,
const QDoubleList &elevationsMeters, const QDoubleList &verticalOffsetsMeters);
const QDoubleList &elevationsMeters, const QBoolList &waterFlags, const QDoubleList &verticalOffsetsMeters);
//! @}
//! Disconnect from DBus

View File

@@ -155,15 +155,16 @@ namespace BlackSimPlugin
{
std::function<void(QDBusPendingCallWatcher *)> callback = [ = ](QDBusPendingCallWatcher * watcher)
{
QDBusPendingReply<QStringList, QList<double>, QList<double>, QList<double>, QList<double>> reply = *watcher;
QDBusPendingReply<QStringList, QList<double>, QList<double>, QList<double>, QList<bool>, QList<double>> reply = *watcher;
if (!reply.isError())
{
const QStringList callsigns = reply.argumentAt<0>();
const QList<double> latitudesDeg = reply.argumentAt<1>();
const QList<double> longitudesDeg = reply.argumentAt<2>();
const QList<double> elevationsM = reply.argumentAt<3>();
const QList<double> verticalOffsets = reply.argumentAt<4>();
setter(callsigns, latitudesDeg, longitudesDeg, elevationsM, verticalOffsets);
const QList<bool> waterFlags = reply.argumentAt<4>();
const QList<double> verticalOffsets = reply.argumentAt<5>();
setter(callsigns, latitudesDeg, longitudesDeg, elevationsM, waterFlags, verticalOffsets);
}
watcher->deleteLater();
};
@@ -175,7 +176,7 @@ namespace BlackSimPlugin
{
std::function<void(QDBusPendingCallWatcher *)> callback = [ = ](QDBusPendingCallWatcher * watcher)
{
QDBusPendingReply<QString, double, double, double> reply = *watcher;
QDBusPendingReply<QString, double, double, double, bool> reply = *watcher;
if (!reply.isError())
{
const CCallsign cs(reply.argumentAt<0>());
@@ -186,8 +187,9 @@ namespace BlackSimPlugin
const CElevationPlane elevation(CLatitude(latitudeDegrees, CAngleUnit::deg()),
CLongitude(longitudeDegrees, CAngleUnit::deg()),
elevationAlt, CElevationPlane::singlePointRadius());
setter(elevation, cs);
// CLogMessage(this).debug(u"XPlane elv. response: '%1' %2 %3 %4") << cs.asString() << latitudeDeg << longitudeDeg << elevationMeters;
const bool isWater = reply.argumentAt<4>();
setter(elevation, cs, isWater);
// CLogMessage(this).debug(u"XPlane elv. response: '%1' %2 %3 %4 %5") << cs.asString() << latitudeDeg << longitudeDeg << elevationMeters << isWater;
}
watcher->deleteLater();
};

View File

@@ -38,6 +38,9 @@ namespace BlackSimPlugin
//! List of doubles
using QDoubleList = QList<double>;
//! List of bools
using QBoolList = QList<bool>;
//! Planes positions
struct PlanesPositions
{
@@ -155,10 +158,10 @@ namespace BlackSimPlugin
public:
//! Elevation callback
using ElevationCallback = std::function<void (const BlackMisc::Geo::CElevationPlane &, const BlackMisc::Aviation::CCallsign &)>;
using ElevationCallback = std::function<void (const BlackMisc::Geo::CElevationPlane &, const BlackMisc::Aviation::CCallsign &, bool)>;
//! Remote aircrafts data callback
using RemoteAircraftDataCallback = std::function<void (const QStringList &, const QDoubleList &, const QDoubleList &, const QDoubleList &, const QDoubleList &)>;
using RemoteAircraftDataCallback = std::function<void (const QStringList &, const QDoubleList &, const QDoubleList &, const QDoubleList &, const QBoolList &, const QDoubleList &)>;
//! Service name
static const QString &InterfaceName()

View File

@@ -79,6 +79,7 @@ R"XML(<node>
<arg name="latitudesDeg" type="ad" direction="out"/>
<arg name="longitudesDeg" type="ad" direction="out"/>
<arg name="elevationsM" type="ad" direction="out"/>
<arg name="waterFlags" type="ab" direction="out"/>
<arg name="verticalOffsets" type="ad" direction="out"/>
</method>
<method name="getElevationAtPosition">
@@ -90,6 +91,7 @@ R"XML(<node>
<arg type="d" direction="out"/>
<arg type="d" direction="out"/>
<arg type="d" direction="out"/>
<arg type="b" direction="out"/>
</method>
<method name="setFollowedAircraft">
<arg name="callsign" type="s" direction="in"/>

View File

@@ -18,7 +18,7 @@ namespace XSwiftBus
CTerrainProbe::~CTerrainProbe() { XPLMDestroyProbe(m_ref); }
std::array<double, 3> CTerrainProbe::getElevation(double degreesLatitude, double degreesLongitude, double metersAltitude, const std::string &callsign) const
std::array<double, 3> CTerrainProbe::getElevation(double degreesLatitude, double degreesLongitude, double metersAltitude, const std::string &callsign, bool &o_isWater) const
{
double x, y, z;
XPLMWorldToLocal(degreesLatitude, degreesLongitude, metersAltitude, &x, &y, &z);
@@ -38,6 +38,7 @@ namespace XSwiftBus
WARNING_LOG(callsign + " " + error + " at " + std::to_string(degreesLatitude) + ", " + std::to_string(degreesLongitude) + ", " + std::to_string(metersAltitude));
}
o_isWater = false;
return {{ std::numeric_limits<double>::quiet_NaN(), degreesLatitude, degreesLongitude }};
}
XPLMLocalToWorld(probe.locationX, probe.locationY, probe.locationZ, &degreesLatitude, &degreesLongitude, &metersAltitude);
@@ -52,6 +53,7 @@ namespace XSwiftBus
m_logMessageCount++;
DEBUG_LOG(callsign + " probe returned NaN at " + std::to_string(degreesLatitude) + ", " + std::to_string(degreesLongitude) + ", " + std::to_string(metersAltitude));
}
o_isWater = probe.is_wet;
return {{ metersAltitude, degreesLatitude, degreesLongitude }};
}
} // ns

View File

@@ -36,7 +36,7 @@ namespace XSwiftBus
//! Get the elevation in meters at the given point in OpenGL space.
//! \note Due to the Earth's curvature, the OpenGL vertical axis may not be exactly perpendicular to the surface of the geoid.
//! \return NaN if no ground was detected.
std::array<double, 3> getElevation(double degreesLatitude, double degreesLongitude, double metersAltitude, const std::string &callsign) const;
std::array<double, 3> getElevation(double degreesLatitude, double degreesLongitude, double metersAltitude, const std::string &callsign, bool &o_isWater) const;
private:
XPLMProbeRef m_ref = nullptr;

View File

@@ -488,7 +488,7 @@ namespace XSwiftBus
}
void CTraffic::getRemoteAircraftData(std::vector<std::string> &callsigns, std::vector<double> &latitudesDeg, std::vector<double> &longitudesDeg,
std::vector<double> &elevationsM, std::vector<double> &verticalOffsets) const
std::vector<double> &elevationsM, std::vector<bool> &waterFlags, std::vector<double> &verticalOffsets) const
{
if (callsigns.empty() || m_planesByCallsign.empty()) { return; }
@@ -510,10 +510,11 @@ namespace XSwiftBus
const double latDeg = plane->position.lat;
const double lonDeg = plane->position.lon;
double groundElevation = 0.0;
bool isWater = false;
if (getSettings().isTerrainProbeEnabled())
{
// we expect elevation in meters
groundElevation = plane->terrainProbe.getElevation(latDeg, lonDeg, plane->position.elevation, requestedCallsign).front();
groundElevation = plane->terrainProbe.getElevation(latDeg, lonDeg, plane->position.elevation, requestedCallsign, isWater).front();
if (std::isnan(groundElevation)) { groundElevation = 0.0; }
}
double fudgeFactor = 3.0;
@@ -523,11 +524,12 @@ namespace XSwiftBus
latitudesDeg.push_back(latDeg);
longitudesDeg.push_back(lonDeg);
elevationsM.push_back(groundElevation);
waterFlags.push_back(isWater);
verticalOffsets.push_back(hasOffset ? fudgeFactor : std::numeric_limits<decltype(fudgeFactor)>::quiet_NaN());
}
}
std::array<double, 3> CTraffic::getElevationAtPosition(const std::string &callsign, double latitudeDeg, double longitudeDeg, double altitudeMeters) const
std::array<double, 3> CTraffic::getElevationAtPosition(const std::string &callsign, double latitudeDeg, double longitudeDeg, double altitudeMeters, bool &o_isWater) const
{
if (!getSettings().isTerrainProbeEnabled()) { return {{ std::numeric_limits<double>::quiet_NaN(), latitudeDeg, longitudeDeg }}; }
@@ -535,11 +537,11 @@ namespace XSwiftBus
if (planeIt != m_planesByCallsign.end())
{
const Plane *plane = planeIt->second;
return plane->terrainProbe.getElevation(latitudeDeg, longitudeDeg, altitudeMeters, callsign);
return plane->terrainProbe.getElevation(latitudeDeg, longitudeDeg, altitudeMeters, callsign, o_isWater);
}
else
{
return m_terrainProbe.getElevation(latitudeDeg, longitudeDeg, altitudeMeters, callsign + " (plane not found)");
return m_terrainProbe.getElevation(latitudeDeg, longitudeDeg, altitudeMeters, callsign + " (plane not found)", o_isWater);
}
}
@@ -798,8 +800,9 @@ namespace XSwiftBus
std::vector<double> latitudesDeg;
std::vector<double> longitudesDeg;
std::vector<double> elevationsM;
std::vector<bool> waterFlags;
std::vector<double> verticalOffsets;
getRemoteAircraftData(callsigns, latitudesDeg, longitudesDeg, elevationsM, verticalOffsets);
getRemoteAircraftData(callsigns, latitudesDeg, longitudesDeg, elevationsM, waterFlags, verticalOffsets);
CDBusMessage reply = CDBusMessage::createReply(sender, serial);
reply.beginArgumentWrite();
reply.appendArgument(callsigns);
@@ -823,13 +826,15 @@ namespace XSwiftBus
message.getArgument(altitudeMeters);
queueDBusCall([ = ]()
{
const auto elevation = getElevationAtPosition(callsign, latitudeDeg, longitudeDeg, altitudeMeters);
bool isWater = false;
const auto elevation = getElevationAtPosition(callsign, latitudeDeg, longitudeDeg, altitudeMeters, isWater);
CDBusMessage reply = CDBusMessage::createReply(sender, serial);
reply.beginArgumentWrite();
reply.appendArgument(callsign);
reply.appendArgument(elevation[0]);
reply.appendArgument(elevation[1]);
reply.appendArgument(elevation[2]);
reply.appendArgument(isWater);
sendDBusMessage(reply);
});
}

View File

@@ -115,10 +115,10 @@ namespace XSwiftBus
//! Get remote aircrafts data (lat, lon, elevation and CG)
void getRemoteAircraftData(std::vector<std::string> &callsigns, std::vector<double> &latitudesDeg, std::vector<double> &longitudesDeg,
std::vector<double> &elevationsM, std::vector<double> &verticalOffsets) const;
std::vector<double> &elevationsM, std::vector<bool> &waterFlags, std::vector<double> &verticalOffsets) const;
//! Get the ground elevation at an arbitrary position
std::array<double, 3> getElevationAtPosition(const std::string &callsign, double latitudeDeg, double longitudeDeg, double altitudeMeters) const;
std::array<double, 3> getElevationAtPosition(const std::string &callsign, double latitudeDeg, double longitudeDeg, double altitudeMeters, bool &o_isWater) const;
//! Sets the aircraft with callsign to be followed in plane view
void setFollowedAircraft(const std::string &callsign);