mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
Simulator driver fetches and injects weather from weather manager
This commit is contained in:
@@ -81,7 +81,7 @@ namespace BlackMisc
|
||||
|
||||
private:
|
||||
BlackMisc::Aviation::CAltitude m_level;
|
||||
PhysicalQuantities::CTemperature m_temperature;
|
||||
PhysicalQuantities::CTemperature m_temperature = { 15.0, PhysicalQuantities::CTemperatureUnit::C() };
|
||||
PhysicalQuantities::CTemperature m_dewPoint;
|
||||
double m_relativeHumidity = 0;
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace BlackMisc
|
||||
private:
|
||||
BlackMisc::Aviation::CAltitude m_base;
|
||||
BlackMisc::Aviation::CAltitude m_top;
|
||||
PhysicalQuantities::CLength m_visibility;
|
||||
PhysicalQuantities::CLength m_visibility { 10, PhysicalQuantities::CLengthUnit::km() };
|
||||
|
||||
BLACK_METACLASS(
|
||||
CVisibilityLayer,
|
||||
|
||||
@@ -133,11 +133,6 @@ namespace BlackSimPlugin
|
||||
m_fsuipc->connect(); // connect FSUIPC too
|
||||
}
|
||||
m_dispatchTimerId = startTimer(50);
|
||||
|
||||
// Pull weather data from core.
|
||||
// Since we don't get weather data from core yet, use hard coded weather.
|
||||
injectWeatherGrid(CWeatherGrid::getCavokGrid());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -333,7 +328,17 @@ namespace BlackSimPlugin
|
||||
{
|
||||
MPPositionVelocity mpPositionVelocity;
|
||||
MultiPlayerPacketParser::readMessage(message, mpPositionVelocity);
|
||||
updateOwnSituation(aircraftSituationfromFS9(mpPositionVelocity));
|
||||
auto aircraftSituation = aircraftSituationfromFS9(mpPositionVelocity);
|
||||
updateOwnSituation(aircraftSituation);
|
||||
|
||||
const auto currentPosition = CCoordinateGeodetic { aircraftSituation.latitude(), aircraftSituation.longitude(), {0} };
|
||||
if (calculateGreatCircleDistance(m_lastWeatherPosition, currentPosition).value(CLengthUnit::mi()) > 20 )
|
||||
{
|
||||
m_lastWeatherPosition = currentPosition;
|
||||
const auto weatherGrid = CWeatherGrid { { "GLOB", currentPosition } };
|
||||
requestWeatherGrid(weatherGrid, { this, &CSimulatorFs9::injectWeatherGrid });
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CFs9Sdk::MPCHAT_PACKET_ID_CHAT_TEXT_SEND:
|
||||
|
||||
@@ -115,6 +115,8 @@ namespace BlackSimPlugin
|
||||
bool m_simConnected = false; //!< Is simulator connected?
|
||||
QSharedPointer<CFs9Host> m_fs9Host;
|
||||
QSharedPointer<CLobbyClient> m_lobbyClient;
|
||||
|
||||
BlackMisc::Geo::CCoordinateGeodetic m_lastWeatherPosition; //!< Own aircraft position at which weather was fetched and injected last
|
||||
};
|
||||
|
||||
//! Listener for FS9
|
||||
|
||||
@@ -123,17 +123,26 @@ namespace BlackSimPlugin
|
||||
// todo: Take station from weather grid
|
||||
memcpy(nw.chICAO, "GLOB", 4);
|
||||
|
||||
const CVisibilityLayerList visibilityLayers = gridPoint.getVisibilityLayers();
|
||||
CVisibilityLayerList visibilityLayers = gridPoint.getVisibilityLayers();
|
||||
visibilityLayers.sortBy(&CVisibilityLayer::getBase);
|
||||
auto surfaceVisibility = visibilityLayers.frontOrDefault();
|
||||
NewVis vis;
|
||||
vis.LowerAlt = surfaceVisibility.getBase().value(CLengthUnit::m());
|
||||
vis.UpperAlt = surfaceVisibility.getTop().value(CLengthUnit::m());
|
||||
// Range is measured in: 1/100ths sm
|
||||
vis.Range = surfaceVisibility.getVisibility().value(CLengthUnit::SM()) * 100;
|
||||
nw.Vis = vis;
|
||||
|
||||
for (const auto &visibilityLayer : visibilityLayers)
|
||||
{
|
||||
NewVis vis;
|
||||
vis.LowerAlt = visibilityLayer.getBase().value(CLengthUnit::m());
|
||||
vis.UpperAlt = visibilityLayer.getTop().value(CLengthUnit::m());
|
||||
vis.Range = visibilityLayer.getVisibility().value(CLengthUnit::mi()) * 100;
|
||||
nw.Vis = vis;
|
||||
vis.Range = visibilityLayer.getVisibility().value(CLengthUnit::SM()) * 100;
|
||||
nw.UpperVis[nw.nUpperVisCtr++] = vis;
|
||||
}
|
||||
|
||||
const CTemperatureLayerList temperatureLayers = gridPoint.getTemperatureLayers();
|
||||
CTemperatureLayerList temperatureLayers = gridPoint.getTemperatureLayers();
|
||||
temperatureLayers.sortBy(&CTemperatureLayer::getLevel);
|
||||
for (const auto &temperatureLayer : temperatureLayers)
|
||||
{
|
||||
NewTemp temp;
|
||||
@@ -144,7 +153,8 @@ namespace BlackSimPlugin
|
||||
nw.Temp[nw.nTempCtr++] = temp;
|
||||
}
|
||||
|
||||
const CCloudLayerList cloudLayers = gridPoint.getCloudLayers();
|
||||
CCloudLayerList cloudLayers = gridPoint.getCloudLayers();
|
||||
cloudLayers.sortBy(&CCloudLayer::getBase);
|
||||
for (const auto &cloudLayer : cloudLayers)
|
||||
{
|
||||
NewCloud cloud;
|
||||
@@ -184,12 +194,13 @@ namespace BlackSimPlugin
|
||||
default: cloud.Type = 0;
|
||||
}
|
||||
|
||||
cloud.UpperAlt = cloudLayer.getBase().value(CLengthUnit::m());
|
||||
cloud.UpperAlt = cloudLayer.getTop().value(CLengthUnit::m());
|
||||
nw.Cloud[nw.nCloudsCtr++] = cloud;
|
||||
}
|
||||
|
||||
const CWindLayerList windLayers = gridPoint.getWindLayers();
|
||||
for (const auto &windLayer : windLayers)
|
||||
CWindLayerList windLayers = gridPoint.getWindLayers();
|
||||
windLayers.sortBy(&CWindLayer::getLevel);
|
||||
for (const auto &windLayer : as_const(windLayers))
|
||||
{
|
||||
NewWind wind;
|
||||
wind.Direction = windLayer.getDirection().value(CAngleUnit::deg()) * 65536 / 360.0;
|
||||
@@ -206,7 +217,8 @@ namespace BlackSimPlugin
|
||||
|
||||
NewPress press;
|
||||
press.Drift = 0;
|
||||
press.Pressure = 15827; // 16 x mb
|
||||
// Pressure is measured in: 16 x mb
|
||||
press.Pressure = gridPoint.getSurfacePressure().value(CPressureUnit::mbar()) * 16;
|
||||
nw.Press = press;
|
||||
|
||||
QByteArray weatherData(reinterpret_cast<const char *>(&nw), sizeof(NewWeather));
|
||||
|
||||
@@ -97,10 +97,6 @@ namespace BlackSimPlugin
|
||||
m_simconnectTimerId = startTimer(10);
|
||||
m_simConnected = true;
|
||||
emitSimulatorCombinedStatus();
|
||||
|
||||
// Pull weather data from core.
|
||||
// Since we don't get weather data from core yet, use hard coded weather.
|
||||
injectWeatherGrid(CWeatherGrid::getCavokGrid());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -431,6 +427,14 @@ namespace BlackSimPlugin
|
||||
{
|
||||
--m_skipCockpitUpdateCycles;
|
||||
}
|
||||
|
||||
const auto currentPosition = CCoordinateGeodetic { aircraftSituation.latitude(), aircraftSituation.longitude(), {0} };
|
||||
if (calculateGreatCircleDistance(m_lastWeatherPosition, currentPosition).value(CLengthUnit::mi()) > 20 )
|
||||
{
|
||||
m_lastWeatherPosition = currentPosition;
|
||||
const auto weatherGrid = CWeatherGrid { { "GLOB", currentPosition } };
|
||||
requestWeatherGrid(weatherGrid, { this, &CSimulatorFsx::injectWeatherGrid });
|
||||
}
|
||||
}
|
||||
|
||||
void CSimulatorFsx::updateOwnAircraftFromSimulator(DataDefinitionClientAreaSb sbDataArea)
|
||||
|
||||
@@ -201,6 +201,8 @@ namespace BlackSimPlugin
|
||||
qint64 m_statsUpdateAircraftTimeTotal = 0;
|
||||
qint64 m_statsUpdateAircraftTimeAvg = 0;
|
||||
int m_statsUpdateAircraftCount = 0;
|
||||
|
||||
BlackMisc::Geo::CCoordinateGeodetic m_lastWeatherPosition; //!< Own aircraft position at which weather was fetched and injected last
|
||||
};
|
||||
|
||||
//! Listener for FSX
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QTimer>
|
||||
#include <QString>
|
||||
#include <functional>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Aviation;
|
||||
@@ -126,6 +127,14 @@ namespace BlackSimPlugin
|
||||
Aviation::CTransponder::getStandardTransponder(m_xplaneData.xpdrCode, xpdrMode(m_xplaneData.xpdrMode, m_xplaneData.xpdrIdent)),
|
||||
identifier()
|
||||
);
|
||||
|
||||
const auto currentPosition = CCoordinateGeodetic { situation.latitude(), situation.longitude(), {0} };
|
||||
if (calculateGreatCircleDistance(m_lastWeatherPosition, currentPosition).value(CLengthUnit::mi()) > 20 )
|
||||
{
|
||||
m_lastWeatherPosition = currentPosition;
|
||||
const auto weatherGrid = CWeatherGrid { { "", currentPosition } };
|
||||
requestWeatherGrid(weatherGrid, { this, &CSimulatorXPlane::injectWeatherGrid });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,10 +219,6 @@ namespace BlackSimPlugin
|
||||
m_traffic->updateInstalledModels();
|
||||
m_watcher->setConnection(m_conn);
|
||||
emitSimulatorCombinedStatus();
|
||||
|
||||
// Pull weather data from core.
|
||||
// Since we don't get weather data from core yet, use hard coded weather.
|
||||
injectWeatherGrid(CWeatherGrid::getCavokGrid());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -525,21 +530,30 @@ namespace BlackSimPlugin
|
||||
CGridPoint gridPoint = weatherGrid.front();
|
||||
|
||||
// todo: find the closest
|
||||
const CVisibilityLayer visibilityLayer = gridPoint.getVisibilityLayers().frontOrDefault();
|
||||
auto visibilityLayers = gridPoint.getVisibilityLayers();
|
||||
visibilityLayers.sortBy(&CVisibilityLayer::getBase);
|
||||
const CVisibilityLayer visibilityLayer = visibilityLayers.frontOrDefault();
|
||||
m_weather->setVisibility(visibilityLayer.getVisibility().value(CLengthUnit::m()));
|
||||
|
||||
const CTemperatureLayer temperatureLayer = gridPoint.getTemperatureLayers().frontOrDefault();
|
||||
CTemperatureLayerList temperatureLayers = gridPoint.getTemperatureLayers();
|
||||
temperatureLayers.sortBy(&CTemperatureLayer::getLevel);
|
||||
const CTemperatureLayer temperatureLayer = temperatureLayers.frontOrDefault();
|
||||
m_weather->setTemperature(temperatureLayer.getTemperature().value(CTemperatureUnit::C()));
|
||||
m_weather->setDewPoint(temperatureLayer.getDewPoint().value(CTemperatureUnit::C()));
|
||||
|
||||
CPressure pressure(989.1875, CPressureUnit::hPa());
|
||||
m_weather->setQNH(pressure.value(CPressureUnit::inHg()));
|
||||
|
||||
m_weather->setPrecipitationRatio(1.0);
|
||||
m_weather->setThunderstormRatio(1.0);
|
||||
m_weather->setQNH(gridPoint.getSurfacePressure().value(CPressureUnit::inHg()));
|
||||
|
||||
int layerNumber = 0;
|
||||
const CCloudLayerList cloudLayers = gridPoint.getCloudLayers();
|
||||
CCloudLayerList cloudLayers = gridPoint.getCloudLayers();
|
||||
auto numberOfLayers = cloudLayers.size();
|
||||
// Fill cloud layers if less then 3
|
||||
while (numberOfLayers < 3)
|
||||
{
|
||||
cloudLayers.push_back(CCloudLayer());
|
||||
numberOfLayers++;
|
||||
}
|
||||
cloudLayers.sortBy(&CCloudLayer::getBase);
|
||||
// todo: Instead of truncate, find the 3 vertical closest cloud layers
|
||||
cloudLayers.truncate(3);
|
||||
for (const auto &cloudLayer : cloudLayers)
|
||||
{
|
||||
int base = cloudLayer.getBase().value(CLengthUnit::m());
|
||||
@@ -563,14 +577,36 @@ namespace BlackSimPlugin
|
||||
case CCloudLayer::NoClouds: type = 0; break;
|
||||
case CCloudLayer::Cirrus: type = 1; break;
|
||||
case CCloudLayer::Stratus: type = 5; break;
|
||||
//case CCloudLayer::Cumulus: cloud.Type = 9; break;
|
||||
//case CCloudLayer::Thunderstorm: cloud.Type = 10; break;
|
||||
default: type = 0;
|
||||
}
|
||||
|
||||
m_weather->setCloudLayer(layerNumber, base, top, type, coverage);
|
||||
layerNumber++;
|
||||
}
|
||||
|
||||
layerNumber = 0;
|
||||
CWindLayerList windLayers = gridPoint.getWindLayers();
|
||||
numberOfLayers = windLayers.size();
|
||||
// Fill cloud layers if less then 3
|
||||
while (numberOfLayers < 3)
|
||||
{
|
||||
windLayers.push_back(CWindLayer());
|
||||
numberOfLayers++;
|
||||
}
|
||||
windLayers.sortBy(&CWindLayer::getLevel);
|
||||
// todo: Instead of truncate, find the 3 vertical closest cloud layers
|
||||
windLayers.truncate(3);
|
||||
for (const auto &windLayer : windLayers)
|
||||
{
|
||||
int altitudeMeter = windLayer.getLevel().value(CLengthUnit::m());
|
||||
double directionDeg = windLayer.getDirection().value(CAngleUnit::deg());
|
||||
int speedKts = windLayer.getSpeed().value(CSpeedUnit::kts());
|
||||
m_weather->setWindLayer(layerNumber, altitudeMeter, directionDeg, speedKts, 0, 0, 0);
|
||||
layerNumber++;
|
||||
}
|
||||
|
||||
m_weather->setPrecipitationRatio(cloudLayers.frontOrDefault().getPrecipitationRate());
|
||||
m_weather->setThunderstormRatio(0.0);
|
||||
}
|
||||
|
||||
BlackCore::ISimulator *CSimulatorXPlaneFactory::create(const CSimulatorPluginInfo &info,
|
||||
|
||||
@@ -152,6 +152,8 @@ namespace BlackSimPlugin
|
||||
BlackMisc::Simulation::CAircraftModelList m_installedModels;
|
||||
BlackMisc::Simulation::CAircraftMatcher m_modelMatcher { BlackMisc::Simulation::CAircraftMatcher::AllModes, this }; //!< Model matcher
|
||||
|
||||
BlackMisc::Geo::CCoordinateGeodetic m_lastWeatherPosition; //!< Own aircraft position at which weather was fetched and injected last
|
||||
|
||||
//! \todo Add units to members? pitchDeg?, altitudeFt?
|
||||
struct // data is written by DBus async method callbacks
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user