Simulator driver fetches and injects weather from weather manager

This commit is contained in:
Roland Winklmeier
2016-03-28 20:57:39 +02:00
parent 5801962a99
commit 781707fb7e
9 changed files with 100 additions and 37 deletions

View File

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

View File

@@ -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,

View File

@@ -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:

View File

@@ -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

View File

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

View File

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

View File

@@ -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

View File

@@ -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,

View File

@@ -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
{