From b09439afb118c3b23d2509ce42d221b027c5625a Mon Sep 17 00:00:00 2001 From: teixeluis Date: Wed, 23 Jun 2021 23:52:15 +0100 Subject: [PATCH] Fixed the mixing of aircraft coordinates in the details view, by checking if the ICAO address of the frame and the current item in the details view match. Slight refactor by placing the decimal to string conversion function into the string_format module. --- firmware/application/apps/ui_adsb_rx.cpp | 38 +++++++++--------------- firmware/application/apps/ui_adsb_rx.hpp | 2 ++ firmware/application/string_format.cpp | 17 +++++++++++ firmware/application/string_format.hpp | 2 ++ firmware/application/ui/ui_geomap.cpp | 14 ++------- firmware/common/adsb.cpp | 12 ++++---- firmware/common/adsb.hpp | 2 +- 7 files changed, 45 insertions(+), 42 deletions(-) diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index b91771b4..88474923 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -20,6 +20,7 @@ * Boston, MA 02110-1301, USA. */ +#include #include "ui_adsb_rx.hpp" #include "ui_alphanum.hpp" @@ -234,49 +235,38 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) { entry.set_frame_pos(frame, raw_data[6] & 4); if (entry.pos.valid) { - std::string latitude_str(8, '\0'); - std::string longitude_str(8, '\0'); - - int written = std::snprintf(&latitude_str[0], latitude_str.size(), "%.2f", entry.pos.latitude); - latitude_str.resize(written); - - written = std::snprintf(&longitude_str[0], longitude_str.size(), "%.2f", entry.pos.longitude); - longitude_str.resize(written); - str_info = "Alt:" + to_string_dec_int(entry.pos.altitude) + - " Lat:" + latitude_str + - " Lon:" + longitude_str; + " Lat:" + to_string_decimal(entry.pos.latitude, 2) + + " Lon:" + to_string_decimal(entry.pos.longitude, 2); // printing the coordinates in the log file with more // resolution, as we are not constrained by screen // real estate there: - latitude_str.resize(13, '\0'); - longitude_str.resize(13, '\0'); - - written = std::snprintf(&latitude_str[0], latitude_str.size(), "%.7f", entry.pos.latitude); - latitude_str.resize(written); - - written = std::snprintf(&longitude_str[0], longitude_str.size(), "%.7f", entry.pos.longitude); - longitude_str.resize(written); - std::string log_info = "Alt:" + to_string_dec_int(entry.pos.altitude) + - " Lat:" + latitude_str + - " Lon:" + longitude_str; + " Lat:" + to_string_decimal(entry.pos.latitude, 7) + + " Lon:" + to_string_decimal(entry.pos.longitude, 7); entry.set_info_string(str_info); logentry+=log_info + " "; - if (send_updates) + if(send_updates && details_view->get_current_entry().ICAO_address == ICAO_address) { + // we only want to update the details view if the frame + // we received has the same ICAO address, i.e. belongs to + // the same aircraft: details_view->update(entry); + } } } else if(msg_type == AIRBORNE_VEL && msg_sub >= VEL_GND_SUBSONIC && msg_sub <= VEL_AIR_SUPERSONIC){ entry.set_frame_velo(frame); logentry += "Type:" + to_string_dec_uint(msg_sub) + " Hdg:" + to_string_dec_uint(entry.velo.heading) + " Spd: "+ to_string_dec_int(entry.velo.speed); - if (send_updates) + + if (send_updates && details_view->get_current_entry().ICAO_address == ICAO_address) { + // same here: details_view->update(entry); + } } } recent_entries_view.set_dirty(); diff --git a/firmware/application/apps/ui_adsb_rx.hpp b/firmware/application/apps/ui_adsb_rx.hpp index a63b7eb2..c55ec680 100644 --- a/firmware/application/apps/ui_adsb_rx.hpp +++ b/firmware/application/apps/ui_adsb_rx.hpp @@ -161,6 +161,8 @@ public: void update(const AircraftRecentEntry& entry); std::string title() const override { return "Details"; }; + + AircraftRecentEntry get_current_entry() { return entry_copy; } private: AircraftRecentEntry entry_copy { 0 }; diff --git a/firmware/application/string_format.cpp b/firmware/application/string_format.cpp index 1aa365e6..c639923e 100644 --- a/firmware/application/string_format.cpp +++ b/firmware/application/string_format.cpp @@ -112,6 +112,23 @@ std::string to_string_dec_int( return q; } +std::string to_string_decimal(float decimal, int8_t precision) { + double integer_part; + double fractional_part; + + std::string result; + + fractional_part = modf(decimal, &integer_part) * pow(10, precision); + + if (fractional_part < 0) { + fractional_part = -fractional_part; + } + + result = to_string_dec_int(integer_part) + "." + to_string_dec_uint(fractional_part, precision); + + return result; +} + std::string to_string_short_freq(const uint64_t f) { auto final_str = to_string_dec_int(f / 1000000,4) + "." + to_string_dec_int((f / 100) % 10000, 4, '0'); return final_str; diff --git a/firmware/application/string_format.hpp b/firmware/application/string_format.hpp index 0555db8e..a588ef95 100644 --- a/firmware/application/string_format.hpp +++ b/firmware/application/string_format.hpp @@ -43,6 +43,8 @@ const char unit_prefix[7] { 'n', 'u', 'm', 0, 'k', 'M', 'G' }; std::string to_string_bin(const uint32_t n, const uint8_t l = 0); std::string to_string_dec_uint(const uint32_t n, const int32_t l = 0, const char fill = ' '); std::string to_string_dec_int(const int32_t n, const int32_t l = 0, const char fill = 0); +std::string to_string_decimal(float decimal, int8_t precision); + std::string to_string_hex(const uint64_t n, const int32_t l = 0); std::string to_string_hex_array(uint8_t * const array, const int32_t l = 0); diff --git a/firmware/application/ui/ui_geomap.cpp b/firmware/application/ui/ui_geomap.cpp index 0f4809dc..1d09880d 100644 --- a/firmware/application/ui/ui_geomap.cpp +++ b/firmware/application/ui/ui_geomap.cpp @@ -63,17 +63,9 @@ GeoPos::GeoPos( const auto changed_fn = [this](int32_t) { float lat_value = lat(); float lon_value = lon(); - double integer_part; - double fractional_part; - - fractional_part = modf(lat_value, &integer_part) * 100000; - if (fractional_part < 0) - fractional_part = -fractional_part; - text_lat_decimal.set(to_string_dec_int(integer_part) + "." + to_string_dec_uint(fractional_part, 5)); - fractional_part = modf(lon_value, &integer_part) * 100000; - if (fractional_part < 0) - fractional_part = -fractional_part; - text_lon_decimal.set(to_string_dec_int(integer_part) + "." + to_string_dec_uint(fractional_part, 5)); + + text_lat_decimal.set(to_string_decimal(lat_value, 5)); + text_lon_decimal.set(to_string_decimal(lon_value, 5)); if (on_change && report_change) on_change(altitude(), lat_value, lon_value); diff --git a/firmware/common/adsb.cpp b/firmware/common/adsb.cpp index f43ff478..3d0e43ef 100644 --- a/firmware/common/adsb.cpp +++ b/firmware/common/adsb.cpp @@ -199,18 +199,18 @@ void encode_frame_pos(ADSBFrame& frame, const uint32_t ICAO_address, const int32 // CPR encoding // Info from: http://antena.fe.uni-lj.si/literatura/Razno/Avionika/modes/CPRencoding.pdf - delta_lat = 360.0 / ((4.0 * 15.0) - time_parity); // NZ = 15 - yz = floor(131072.0 * (cpr_mod(latitude, delta_lat) / delta_lat) + 0.5); - rlat = delta_lat * ((yz / 131072.0) + floor(latitude / delta_lat)); + delta_lat = 360.0 / ((4.0 * NZ) - time_parity); // NZ = 15 + yz = floor(CPR_MAX_VALUE * (cpr_mod(latitude, delta_lat) / delta_lat) + 0.5); + rlat = delta_lat * ((yz / CPR_MAX_VALUE) + floor(latitude / delta_lat)); if ((cpr_NL(rlat) - time_parity) > 0) delta_lon = 360.0 / cpr_N(rlat, time_parity); else delta_lon = 360.0; - xz = floor(131072.0 * (cpr_mod(longitude, delta_lon) / delta_lon) + 0.5); + xz = floor(CPR_MAX_VALUE * (cpr_mod(longitude, delta_lon) / delta_lon) + 0.5); - lat = cpr_mod(yz, 131072.0); - lon = cpr_mod(xz, 131072.0); + lat = cpr_mod(yz, CPR_MAX_VALUE); + lon = cpr_mod(xz, CPR_MAX_VALUE); frame.push_byte((altitude_coded << 4) | ((uint32_t)time_parity << 2) | (lat >> 15)); // T = 0 frame.push_byte(lat >> 7); diff --git a/firmware/common/adsb.hpp b/firmware/common/adsb.hpp index f3a2f3ac..7e4d3bce 100644 --- a/firmware/common/adsb.hpp +++ b/firmware/common/adsb.hpp @@ -85,7 +85,7 @@ const float adsb_lat_lut[58] = { const float PI = 3.14159265358979323846; -const float NZ = 15; +const float NZ = 15.0; void make_frame_adsb(ADSBFrame& frame, const uint32_t ICAO_address);