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: private:
BlackMisc::Aviation::CAltitude m_level; BlackMisc::Aviation::CAltitude m_level;
PhysicalQuantities::CTemperature m_temperature; PhysicalQuantities::CTemperature m_temperature = { 15.0, PhysicalQuantities::CTemperatureUnit::C() };
PhysicalQuantities::CTemperature m_dewPoint; PhysicalQuantities::CTemperature m_dewPoint;
double m_relativeHumidity = 0; double m_relativeHumidity = 0;

View File

@@ -74,7 +74,7 @@ namespace BlackMisc
private: private:
BlackMisc::Aviation::CAltitude m_base; BlackMisc::Aviation::CAltitude m_base;
BlackMisc::Aviation::CAltitude m_top; BlackMisc::Aviation::CAltitude m_top;
PhysicalQuantities::CLength m_visibility; PhysicalQuantities::CLength m_visibility { 10, PhysicalQuantities::CLengthUnit::km() };
BLACK_METACLASS( BLACK_METACLASS(
CVisibilityLayer, CVisibilityLayer,

View File

@@ -133,11 +133,6 @@ namespace BlackSimPlugin
m_fsuipc->connect(); // connect FSUIPC too m_fsuipc->connect(); // connect FSUIPC too
} }
m_dispatchTimerId = startTimer(50); 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; return true;
} }
@@ -333,7 +328,17 @@ namespace BlackSimPlugin
{ {
MPPositionVelocity mpPositionVelocity; MPPositionVelocity mpPositionVelocity;
MultiPlayerPacketParser::readMessage(message, 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; break;
} }
case CFs9Sdk::MPCHAT_PACKET_ID_CHAT_TEXT_SEND: case CFs9Sdk::MPCHAT_PACKET_ID_CHAT_TEXT_SEND:

View File

@@ -115,6 +115,8 @@ namespace BlackSimPlugin
bool m_simConnected = false; //!< Is simulator connected? bool m_simConnected = false; //!< Is simulator connected?
QSharedPointer<CFs9Host> m_fs9Host; QSharedPointer<CFs9Host> m_fs9Host;
QSharedPointer<CLobbyClient> m_lobbyClient; QSharedPointer<CLobbyClient> m_lobbyClient;
BlackMisc::Geo::CCoordinateGeodetic m_lastWeatherPosition; //!< Own aircraft position at which weather was fetched and injected last
}; };
//! Listener for FS9 //! Listener for FS9

View File

@@ -123,17 +123,26 @@ namespace BlackSimPlugin
// todo: Take station from weather grid // todo: Take station from weather grid
memcpy(nw.chICAO, "GLOB", 4); 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) for (const auto &visibilityLayer : visibilityLayers)
{ {
NewVis vis;
vis.LowerAlt = visibilityLayer.getBase().value(CLengthUnit::m()); vis.LowerAlt = visibilityLayer.getBase().value(CLengthUnit::m());
vis.UpperAlt = visibilityLayer.getTop().value(CLengthUnit::m()); vis.UpperAlt = visibilityLayer.getTop().value(CLengthUnit::m());
vis.Range = visibilityLayer.getVisibility().value(CLengthUnit::mi()) * 100; vis.Range = visibilityLayer.getVisibility().value(CLengthUnit::SM()) * 100;
nw.Vis = vis; nw.UpperVis[nw.nUpperVisCtr++] = vis;
} }
const CTemperatureLayerList temperatureLayers = gridPoint.getTemperatureLayers(); CTemperatureLayerList temperatureLayers = gridPoint.getTemperatureLayers();
temperatureLayers.sortBy(&CTemperatureLayer::getLevel);
for (const auto &temperatureLayer : temperatureLayers) for (const auto &temperatureLayer : temperatureLayers)
{ {
NewTemp temp; NewTemp temp;
@@ -144,7 +153,8 @@ namespace BlackSimPlugin
nw.Temp[nw.nTempCtr++] = temp; nw.Temp[nw.nTempCtr++] = temp;
} }
const CCloudLayerList cloudLayers = gridPoint.getCloudLayers(); CCloudLayerList cloudLayers = gridPoint.getCloudLayers();
cloudLayers.sortBy(&CCloudLayer::getBase);
for (const auto &cloudLayer : cloudLayers) for (const auto &cloudLayer : cloudLayers)
{ {
NewCloud cloud; NewCloud cloud;
@@ -184,12 +194,13 @@ namespace BlackSimPlugin
default: cloud.Type = 0; default: cloud.Type = 0;
} }
cloud.UpperAlt = cloudLayer.getBase().value(CLengthUnit::m()); cloud.UpperAlt = cloudLayer.getTop().value(CLengthUnit::m());
nw.Cloud[nw.nCloudsCtr++] = cloud; nw.Cloud[nw.nCloudsCtr++] = cloud;
} }
const CWindLayerList windLayers = gridPoint.getWindLayers(); CWindLayerList windLayers = gridPoint.getWindLayers();
for (const auto &windLayer : windLayers) windLayers.sortBy(&CWindLayer::getLevel);
for (const auto &windLayer : as_const(windLayers))
{ {
NewWind wind; NewWind wind;
wind.Direction = windLayer.getDirection().value(CAngleUnit::deg()) * 65536 / 360.0; wind.Direction = windLayer.getDirection().value(CAngleUnit::deg()) * 65536 / 360.0;
@@ -206,7 +217,8 @@ namespace BlackSimPlugin
NewPress press; NewPress press;
press.Drift = 0; 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; nw.Press = press;
QByteArray weatherData(reinterpret_cast<const char *>(&nw), sizeof(NewWeather)); QByteArray weatherData(reinterpret_cast<const char *>(&nw), sizeof(NewWeather));

View File

@@ -97,10 +97,6 @@ namespace BlackSimPlugin
m_simconnectTimerId = startTimer(10); m_simconnectTimerId = startTimer(10);
m_simConnected = true; m_simConnected = true;
emitSimulatorCombinedStatus(); 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; return true;
} }
@@ -431,6 +427,14 @@ namespace BlackSimPlugin
{ {
--m_skipCockpitUpdateCycles; --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) void CSimulatorFsx::updateOwnAircraftFromSimulator(DataDefinitionClientAreaSb sbDataArea)

View File

@@ -201,6 +201,8 @@ namespace BlackSimPlugin
qint64 m_statsUpdateAircraftTimeTotal = 0; qint64 m_statsUpdateAircraftTimeTotal = 0;
qint64 m_statsUpdateAircraftTimeAvg = 0; qint64 m_statsUpdateAircraftTimeAvg = 0;
int m_statsUpdateAircraftCount = 0; int m_statsUpdateAircraftCount = 0;
BlackMisc::Geo::CCoordinateGeodetic m_lastWeatherPosition; //!< Own aircraft position at which weather was fetched and injected last
}; };
//! Listener for FSX //! Listener for FSX

View File

@@ -18,6 +18,7 @@
#include <QDBusServiceWatcher> #include <QDBusServiceWatcher>
#include <QTimer> #include <QTimer>
#include <QString> #include <QString>
#include <functional>
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Aviation; using namespace BlackMisc::Aviation;
@@ -126,6 +127,14 @@ namespace BlackSimPlugin
Aviation::CTransponder::getStandardTransponder(m_xplaneData.xpdrCode, xpdrMode(m_xplaneData.xpdrMode, m_xplaneData.xpdrIdent)), Aviation::CTransponder::getStandardTransponder(m_xplaneData.xpdrCode, xpdrMode(m_xplaneData.xpdrMode, m_xplaneData.xpdrIdent)),
identifier() 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_traffic->updateInstalledModels();
m_watcher->setConnection(m_conn); m_watcher->setConnection(m_conn);
emitSimulatorCombinedStatus(); 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; return true;
} }
else else
@@ -525,21 +530,30 @@ namespace BlackSimPlugin
CGridPoint gridPoint = weatherGrid.front(); CGridPoint gridPoint = weatherGrid.front();
// todo: find the closest // 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())); 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->setTemperature(temperatureLayer.getTemperature().value(CTemperatureUnit::C()));
m_weather->setDewPoint(temperatureLayer.getDewPoint().value(CTemperatureUnit::C())); m_weather->setDewPoint(temperatureLayer.getDewPoint().value(CTemperatureUnit::C()));
m_weather->setQNH(gridPoint.getSurfacePressure().value(CPressureUnit::inHg()));
CPressure pressure(989.1875, CPressureUnit::hPa());
m_weather->setQNH(pressure.value(CPressureUnit::inHg()));
m_weather->setPrecipitationRatio(1.0);
m_weather->setThunderstormRatio(1.0);
int layerNumber = 0; 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) for (const auto &cloudLayer : cloudLayers)
{ {
int base = cloudLayer.getBase().value(CLengthUnit::m()); int base = cloudLayer.getBase().value(CLengthUnit::m());
@@ -563,14 +577,36 @@ namespace BlackSimPlugin
case CCloudLayer::NoClouds: type = 0; break; case CCloudLayer::NoClouds: type = 0; break;
case CCloudLayer::Cirrus: type = 1; break; case CCloudLayer::Cirrus: type = 1; break;
case CCloudLayer::Stratus: type = 5; break; case CCloudLayer::Stratus: type = 5; break;
//case CCloudLayer::Cumulus: cloud.Type = 9; break;
//case CCloudLayer::Thunderstorm: cloud.Type = 10; break;
default: type = 0; default: type = 0;
} }
m_weather->setCloudLayer(layerNumber, base, top, type, coverage); m_weather->setCloudLayer(layerNumber, base, top, type, coverage);
layerNumber++; 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, BlackCore::ISimulator *CSimulatorXPlaneFactory::create(const CSimulatorPluginInfo &info,

View File

@@ -152,6 +152,8 @@ namespace BlackSimPlugin
BlackMisc::Simulation::CAircraftModelList m_installedModels; BlackMisc::Simulation::CAircraftModelList m_installedModels;
BlackMisc::Simulation::CAircraftMatcher m_modelMatcher { BlackMisc::Simulation::CAircraftMatcher::AllModes, this }; //!< Model matcher 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? //! \todo Add units to members? pitchDeg?, altitudeFt?
struct // data is written by DBus async method callbacks struct // data is written by DBus async method callbacks
{ {