Skip to content

Commit

Permalink
Merge pull request #253 from TwinFan/Next
Browse files Browse the repository at this point in the history
Merge v3.4.0
  • Loading branch information
TwinFan authored May 13, 2023
2 parents d347822 + 4ed74f8 commit 670e3d0
Show file tree
Hide file tree
Showing 30 changed files with 64,411 additions and 222 deletions.
11 changes: 7 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ else()
endif()

project(LiveTraffic
VERSION 3.3.2
VERSION 3.4.0
DESCRIPTION "LiveTraffic X-Plane plugin")

# Provide compile macros from the above project version definition
Expand All @@ -42,9 +42,10 @@ if (WIN32)
set(ENV{platform} "win")
endif()
elseif(APPLE)
set(CMAKE_OSX_DEPLOYMENT_TARGET 11.0)
add_compile_options(-mmacosx-version-min=11.0)
add_link_options(-mmacosx-version-min=11.0)
# MacOS 10.15 is minimum system requirement for X-Plane 12
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15)
add_compile_options(-mmacosx-version-min=10.15)
add_link_options(-mmacosx-version-min=10.15)
endif()

################################################################################
Expand Down Expand Up @@ -139,6 +140,7 @@ set(Header_Files
Include/InfoListWnd.h
Include/LiveTraffic.h
Include/LTADSBEx.h
Include/LTADSBHub.h
Include/LTAircraft.h
Include/LTApt.h
Include/LTChannel.h
Expand Down Expand Up @@ -182,6 +184,7 @@ set(Source_Files
Src/InfoListWnd.cpp
Src/LiveTraffic.cpp
Src/LTADSBEx.cpp
Src/LTADSBHub.cpp
Src/LTAircraft.cpp
Src/LTApt.cpp
Src/LTChannel.cpp
Expand Down
29,508 changes: 29,508 additions & 0 deletions Data/ADSBHub/ADSBHub_SBS_Sample.csv

Large diffs are not rendered by default.

18 changes: 14 additions & 4 deletions Data/ADSBHub/ADSBHub_Test.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@

try:
msgFormat = '' # Will become either 'SBS' or 'C-VRS'
i = 0
i = 0 # Count received messages (with actual content)
iNull = 0 # Count received NULL messages
incomplLn = '' # incomplete beginning of a line from last network message
while(1):
r = sock.recv(4096) # Receive data
i += 1
if (len(r) > 0):
# Received something after a couple of NULLs?
if (iNull > 0):
print ("After {0} NULL messages, now receiving:\n".format(iNull))
iNull = 0

i += 1
# Determine which format we are listening to
if msgFormat == '':
if len(r) >= 30:
Expand Down Expand Up @@ -56,14 +62,18 @@
incomplLn += r # add what's received to what's left over from last msg
l = incomplLn[0] # length of individual msg is in first byte
while(len(incomplLn) >= l): # while buffer contains full msg print it
print (binascii.hexlify(incomplLn[0:l],' ').decode('ascii'))
# print (binascii.hexlify(incomplLn[0:l],' ').decode('ascii'))
# Print Header in 3 parts, showing ICAO in 6 digits, then add data after colon:
print (incomplLn[0:4].hex('-') + '|' + incomplLn[4:7].hex() + '|' + incomplLn[7:9].hex('-') + ': ' + incomplLn[9:l].hex(' '))
if len(incomplLn) > l: # if buffer has _more_ than just the printed msg
incomplLn = incomplLn[l:] # remove printed part (inefficient, makes copies...but well...)
l = incomplLn[0] # and determine length of next msg
else:
incomplLn = b'' # msg fit exactly, clear buffer
else:
print ("{0}. <NULL> {1}".format(i,r))
if (iNull == 0):
print ("Receiving NULL...")
iNull += 1


except OSError as err:
Expand Down
33,783 changes: 33,783 additions & 0 deletions Data/ADSBHub/ADSBHub_VRS_Sample.txt

Large diffs are not rendered by default.

Binary file removed Data/RealTraffic/RTdev2.0.pdf
Binary file not shown.
Binary file not shown.
7 changes: 3 additions & 4 deletions Include/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,9 @@ constexpr double JAN_FIRST_2019 = 1546344000; // 01.01.2019
constexpr double HPA_STANDARD = 1013.25; // air pressure
constexpr double INCH_STANDARD = 29.92126;
constexpr double HPA_per_INCH = HPA_STANDARD/INCH_STANDARD;
// The pressure drops approximately by 11.3 Pa per meter in first 1000 meters above sea level.
constexpr double PA_per_M = 11.3; // https://en.wikipedia.org/wiki/Barometric_formula
// ft altitude diff per hPa change
constexpr double FT_per_HPA = (100/PA_per_M)/M_per_FT;
constexpr double TEMP_STANDARD = 288.15f; ///< Standard temperatur of 15°C in °Kelvin
constexpr double G0_M_R_Lb = 0.1902632365f;///< -(g0 * M) / (R * Lb)
constexpr double TEMP_LAPS_R = -0.0065f; ///< K/m

//MARK: Flight Data-related
constexpr unsigned MAX_TRANSP_ICAO = 0xFFFFFF; // max transponder ICAO code (24bit)
Expand Down
4 changes: 4 additions & 0 deletions Include/CoordCalc.h
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,10 @@ struct boundingBoxTy {

/// Center point of bounding box
positionTy center () const;
/// South-west corner ("minimum")
positionTy sw () const { return positionTy(se.lat(), nw.lon()); }
/// north-east corner ("maximum")
positionTy ne () const { return positionTy(nw.lat(), se.lon()); }

// standard string for any output purposes
operator std::string() const;
Expand Down
14 changes: 3 additions & 11 deletions Include/DataRefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ enum dataRefsLT {
DR_CHANNEL_FSCHARTER,
DR_CHANNEL_OPEN_GLIDER_NET,
DR_CHANNEL_ADSB_EXCHANGE_ONLINE,
DR_CHANNEL_ADSB_EXCHANGE_HISTORIC,
DR_CHANNEL_ADSB_HUB,
DR_CHANNEL_OPEN_SKY_ONLINE,
DR_CHANNEL_OPEN_SKY_AC_MASTERDATA,
DR_CHANNEL_REAL_TRAFFIC_ONLINE, // currently highest-prio channel
Expand Down Expand Up @@ -720,7 +720,6 @@ class DataRefs
const LTAircraft* pAc = nullptr; // ptr to that a/c

// Weather
double altPressCorr_ft = 0.0; ///< [ft] barometric correction for pressure altitude, in meter
float lastWeatherAttempt = 0.0f; ///< last time we _tried_ to update the weather
float lastWeatherUpd = 0.0f; ///< last time the weather was updated? (in XP's network time)
float lastWeatherHPA = HPA_STANDARD; ///< last barometric pressure received
Expand Down Expand Up @@ -1042,15 +1041,8 @@ class DataRefs
/// @details if lat/lon ar NAN, then location of provided station is taken if found, else current camera pos
void SetWeather (float hPa, float lat, float lon, const std::string& stationId,
const std::string& METAR);
/// Compute geometric altitude [ft] from pressure altitude and current weather in a very simplistic manner good enough for the first 3,000ft
static double WeatherAltCorr_ft (double pressureAlt_ft, double hPa)
{ return pressureAlt_ft + ((hPa - HPA_STANDARD) * FT_per_HPA); }
/// Compute geometric altitude [ft] from pressure altitude and current weather in a very simplistic manner good enough for the first 3,000ft
double WeatherAltCorr_ft (double pressureAlt_ft) { return pressureAlt_ft + altPressCorr_ft; }
/// Compute geometric altitude [m] from pressure altitude and current weather in a very simplistic manner good enough for the first 3,000ft
double WeatherAltCorr_m (double pressureAlt_m) { return pressureAlt_m + altPressCorr_ft * M_per_FT; }
/// Compute pressure altitude [ft] from geometric altitude and current weather in a very simplistic manner good enough for the first 3,000ft
double WeatherPressureAlt_ft (double geoAlt_ft) { return geoAlt_ft - altPressCorr_ft; }
/// Get current sea level air pressure
double GetPressureHPA() const { return lastWeatherHPA; }
/// Thread-safely gets current weather info
void GetWeather (float& hPa, std::string& stationId, std::string& METAR);

Expand Down
124 changes: 124 additions & 0 deletions Include/LTADSBHub.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/// @file LTADSBHub.h
/// @brief ADSBHub: Processes live tracking data
/// @see https://www.adsbhub.org/howtogetdata.php
/// @details Defines ADSBHubConnection:
/// - Direct TCP connection to data.adsbhub.org:5002
/// - connects to the server
/// - listens to incoming tracking data
/// @author Birger Hoppe
/// @copyright (c) 2023 Birger Hoppe
/// @copyright Permission is hereby granted, free of charge, to any person obtaining a
/// copy of this software and associated documentation files (the "Software"),
/// to deal in the Software without restriction, including without limitation
/// the rights to use, copy, modify, merge, publish, distribute, sublicense,
/// and/or sell copies of the Software, and to permit persons to whom the
/// Software is furnished to do so, subject to the following conditions:\n
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.\n
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.

#ifndef LTADSBHub_h
#define LTADSBHub_h

#include "LTChannel.h"

//
//MARK: ADSBHub Constants
//

#define ADSBHUB_CHECK_NAME "ADSBHub Coverage"
#define ADSBHUB_CHECK_URL "https://www.adsbhub.org/coverage.php"
#define ADSBHUB_CHECK_POPUP "Check ADSBHub's coverage"

//
// MARK: ADSBHubConnection
//

/// Connection to ADSBHub via TCP stream
class ADSBHubConnection : public LTOnlineChannel, LTFlightDataChannel
{
protected:
// the map of flight data, where we deliver our data to
mapLTFlightDataTy& fdMap;

std::thread thrStream; ///< thread for the ADSBHub stream
TCPConnection tcpStream; ///< TCP connection to data.adsbhub.org:5002
volatile bool bStopThr=false; ///< stop signal to the thread
#if APL == 1 || LIN == 1
/// the self-pipe to shut down the TCP thread gracefully
SOCKET streamPipe[2] = { INVALID_SOCKET, INVALID_SOCKET };
#endif

/// Own public IP4 address, only filled if FMT_NULL_DATA
std::string sPublicIPv4addr;

/// ADSBHub format that we receive
enum FormatTy : int {
FMT_UNKNOWN = 0, ///< (yet) unknown format
FMT_SBS, ///< SBS format (CSV text-based)
FMT_ComprVRS, ///< Compressed VRS (binary)
FMT_NULL_DATA, ///< Received null data, indicative of wrong configuration
} eFormat = FMT_UNKNOWN; ///< ADSBHub format that we receive

/// Time of last received data
std::chrono::time_point<std::chrono::steady_clock> lastData;

/// Incomplete line/data left over from previous message
std::string lnLeftOver;

// Plane data currently being collected
LTFlightData::FDKeyTy fdKey; ///< ADS-B hex id currently being processed
LTFlightData::FDStaticData stat;///< static data of plane currently being processed
LTFlightData::FDDynamicData dyn;///< dynamic data of plane currently being processed
positionTy pos; ///< position of plane currently being processed

public:
/// Constructor
ADSBHubConnection (mapLTFlightDataTy& _fdMap);
/// Destructor cleans up
~ADSBHubConnection () override;
/// Invokes APRS thread, or returns URL to fetch current data from live.glidernet.org
std::string GetURL (const positionTy&) override { return ""; }
/// @brief Processes the fetched data
bool ProcessFetchedData (mapLTFlightDataTy&) override { return true; };
bool IsLiveFeed() const override { return true; }
LTChannelType GetChType() const override { return CHT_TRACKING_DATA; }
std::string GetStatusText () const override; ///< return a human-readable staus
bool FetchAllData(const positionTy& pos) override;
void DoDisabledProcessing() override { StreamClose(); }
void Close () override { StreamClose(); }

// ADSBHub Stream connection
protected:
/// Main function for stream connection, expected to be started in a thread
void StreamMain ();
/// Process received SBS data
bool StreamProcessDataSBS (size_t num, const char* buffer);
/// Process a single line of SBS data
bool StreamProcessDataSBSLine (const char* pStart, const char* pEnd);
/// Process received VRS data
bool StreamProcessDataVRS (size_t num, const uint8_t* buffer);
/// Process a single line of C-VRS data
bool StreamProcessDataVRSLine (const uint8_t* pStart);

/// Add the collected data for a plane to LiveTraffic's FlightData and reset the internal buffers
void ProcessPlaneData ();

/// Start or restart a new thread for connecting to ADSBHub
void StreamStart ();
/// Closes the stream TCP connection
void StreamClose ();

};

/// @brief Query https://api.ipify.org/ to get own public IP address
/// @note Blocking call! Should be quick...but don't call too often
std::string GetPublicIPv4 ();

#endif /* LTADSBHub_h */
4 changes: 3 additions & 1 deletion Include/LTImgWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ inline bool TreeNodeLinkHelp(const char* label, int nCol,
filter, nOpCl, flags);
}

/// Does label match filter?
bool MatchesFilter(const char* label, const char* filter);

/// @brief Show this label only if text matches filter string
/// @details All rendering is skipped if `filter` is non-empty but doesn not match `label`.
Expand All @@ -241,7 +243,7 @@ IMGUI_API bool FilteredInputText(const char* label, const char* filter,
/// Otherwise, cursor is at beginning of (next) cell afterwards.
/// @return Value just changed?
IMGUI_API bool FilteredCfgCheckbox(const char* label, const char* filter, dataRefsLT idx,
const char* tooltip = nullptr);
const char* tooltip = nullptr, bool bNextCell = true);

/// @brief Filter label plus checkbox for a bit
/// @details All rendering is skipped if `filter` is non-empty but doesn not match `label`.
Expand Down
22 changes: 4 additions & 18 deletions Include/LTRealTraffic.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/// @see https://rtweb.flyrealtraffic.com/
/// @details Defines RealTrafficConnection:\n
/// - Sends current position to RealTraffic app\n
/// - Receives tracking and weather data via UDP\n
/// - Receives tracking data via UDP\n
/// - Interprets the response and passes the tracking data on to LTFlightData.\n
/// @author Birger Hoppe
/// @copyright (c) 2019-2020 Birger Hoppe
Expand Down Expand Up @@ -41,8 +41,8 @@
#define RT_LOCALHOST "0.0.0.0"
constexpr size_t RT_NET_BUF_SIZE = 8192;

constexpr double RT_SMOOTH_AIRBORNE = 65.0; // smooth 65s of airborne data
constexpr double RT_SMOOTH_GROUND = 35.0; // smooth 35s of ground data
// constexpr double RT_SMOOTH_AIRBORNE = 65.0; // smooth 65s of airborne data
// constexpr double RT_SMOOTH_GROUND = 35.0; // smooth 35s of ground data
constexpr double RT_VSI_AIRBORNE = 80.0; ///< if VSI is more than this then we assume "airborne"

#define MSG_RT_STATUS "RealTraffic network status changed to: %s"
Expand All @@ -52,7 +52,6 @@ constexpr double RT_VSI_AIRBORNE = 80.0; ///< if VSI is more than this then w
#define INFO_RT_REAL_TIME "RealTraffic: Tracking data is real-time again."
#define INFO_RT_ADJUST_TS "RealTraffic: Receive and display past tracking data from %s"
#define ERR_RT_CANTLISTEN "RealTraffic: Cannot listen to network, can't tell RealTraffic our position"
#define ERR_RT_WEATHER_QNH "RealTraffic reports unreasonable QNH %ld - ignored"
#define ERR_RT_DISCARDED_MSG "RealTraffic: Discarded invalid message: %s"
#define ERR_SOCK_NOTCONNECTED "%s: Cannot send position: not connected"
#define ERR_SOCK_INV_POS "%s: Cannot send position: position not fully valid"
Expand Down Expand Up @@ -137,11 +136,6 @@ enum RT_RTTFC_FIELDS_TY {
RT_RTTFC_MIN_TFC_FIELDS ///< always last, minimum number of fields
};

// Weather JSON fields
#define RT_WEATHER_ICAO "ICAO"
#define RT_WEATHER_QNH "QNH"
#define RT_WEATHER_METAR "METAR"

// map of id to last received datagram (for duplicate datagram detection)
struct RTUDPDatagramTy {
double posTime;
Expand Down Expand Up @@ -186,7 +180,6 @@ class RealTrafficConnection : public LTOnlineChannel, LTFlightDataChannel
// udp thread and its sockets
std::thread thrUdpListener;
UDPReceiver udpTrafficData;
UDPReceiver udpWeatherData;
#if APL == 1 || LIN == 1
// the self-pipe to shut down the UDP listener thread gracefully
SOCKET udpPipe[2] = { INVALID_SOCKET, INVALID_SOCKET };
Expand All @@ -196,9 +189,6 @@ class RealTrafficConnection : public LTOnlineChannel, LTFlightDataChannel
double lastReceivedTime = 0.0; // copy of simTime
// map of last received datagrams for duplicate detection
std::map<unsigned long,RTUDPDatagramTy> mapDatagrams;
// weather, esp. current barometric pressure to correct altitude values
std::string lastWeather; // for duplicate detection
bool bWeatherErrHappened = false; ///< Flag: Report UDP errors for weather just once
/// rolling list of timestamp (diff to now) for detecting historic sending
std::deque<double> dequeTS;
/// current timestamp adjustment
Expand Down Expand Up @@ -265,9 +255,8 @@ class RealTrafficConnection : public LTOnlineChannel, LTFlightDataChannel
bool ProcessRecvedTrafficData (const char* traffic);
bool ProcessRTTFC (LTFlightData::FDKeyTy& fdKey, const std::vector<std::string>& tfc); ///< Process a RTTFC type message
bool ProcessAITFC (LTFlightData::FDKeyTy& fdKey, const std::vector<std::string>& tfc); ///< Process a AITFC or XTRAFFICPSX type message
bool ProcessRecvedWeatherData (const char* weather);

/// Determine timestamp adjustment necessairy in case of historic data
/// Determine timestamp adjustment necessary in case of historic data
void AdjustTimestamp (double& ts);
/// Return a string describing the current timestamp adjustment
std::string GetAdjustTSText () const;
Expand All @@ -278,9 +267,6 @@ class RealTrafficConnection : public LTOnlineChannel, LTFlightDataChannel
const char* datagram);
// remove outdated entries from mapDatagrams
void CleanupMapDatagrams();

// initialize weather info
void InitWeather();
};


Expand Down
17 changes: 17 additions & 0 deletions Include/LiveTraffic.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ extern DataRefs dataRefs;
#include "LTRealTraffic.h"
#include "LTOpenSky.h"
#include "LTADSBEx.h"
#include "LTADSBHub.h"
#include "LTOpenGlider.h"
#include "LTFSCharter.h"

Expand Down Expand Up @@ -334,6 +335,22 @@ inline bool CheckEverySoOften (float& _lastCheck, float _interval)

// MARK: Other Utility Functions

/// Convert barometric altitude to pressure at that altitude, assume pressure alt got calculated with standard pressure at sea level in mind
double PressureFromBaroAlt(double baroAlt_m, double refPressure = HPA_STANDARD);
/// Convert a given pressure to an altitude, providing sea level pressure as reference
double AltFromPressure(double pressure, double refPressure);
/// Convert a barometric altitude (based on std pressure) to a geometric altitude
double BaroAltToGeoAlt_m(double baroAlt_m, double refPressure);
/// Convert a barometric altitude (based on std pressure) to a geometric altitude
inline double BaroAltToGeoAlt_ft(double baroAlt_ft, double refPressure)
{ return BaroAltToGeoAlt_m(baroAlt_ft * M_per_FT, refPressure) / M_per_FT; }

/// Convert a geometric altitude to a barometric altitude (based on std pressure)
double GeoAltToBaroAlt_m(double geoAlt_m, double refPressure);
/// Convert a geometric altitude to a barometric altitude (based on std pressure)
inline double GeoAltToBaroAlt_ft(double geoAlt_ft, double refPressure)
{ return GeoAltToBaroAlt_m(geoAlt_ft * M_per_FT, refPressure) / M_per_FT; }

/// Fetch nearest airport id by location
std::string GetNearestAirportId (const positionTy& _pos, positionTy* outApPos = nullptr);

Expand Down
2 changes: 1 addition & 1 deletion Lib/XPMP2
Loading

0 comments on commit 670e3d0

Please sign in to comment.