From f08949acd71eeed1504e049e252888378195774d Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Fri, 24 Jul 2020 16:09:21 -0500 Subject: [PATCH 01/12] Add Heading to ADSB and Map Updating --- firmware/application/apps/ais_app.cpp | 2 +- firmware/application/apps/ui_adsb_rx.cpp | 7 +++- firmware/application/apps/ui_adsb_rx.hpp | 6 ++- firmware/application/ui/ui_geomap.cpp | 20 ++++++---- firmware/application/ui/ui_geomap.hpp | 10 ++--- firmware/common/adsb.cpp | 47 +++++++++++++++++++++++- firmware/common/adsb.hpp | 9 +++++ firmware/common/adsb_frame.hpp | 4 ++ 8 files changed, 87 insertions(+), 18 deletions(-) diff --git a/firmware/application/apps/ais_app.cpp b/firmware/application/apps/ais_app.cpp index 89244e87e..7d42be860 100644 --- a/firmware/application/apps/ais_app.cpp +++ b/firmware/application/apps/ais_app.cpp @@ -240,7 +240,7 @@ AISRecentEntryDetailView::AISRecentEntryDetailView(NavigationView& nav) { void AISRecentEntryDetailView::update_position() { if (send_updates) - geomap_view->update_position(ais::format::latlon_float(entry_.last_position.latitude.normalized()), ais::format::latlon_float(entry_.last_position.longitude.normalized())); + geomap_view->update_position(ais::format::latlon_float(entry_.last_position.latitude.normalized()), ais::format::latlon_float(entry_.last_position.longitude.normalized()), (float)entry_.last_position.true_heading); } void AISRecentEntryDetailView::focus() { diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index 76d22730c..8a174e4cf 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -97,7 +97,7 @@ void ADSBRxDetailsView::update(const AircraftRecentEntry& entry) { text_frame_pos_odd.set(to_string_hex_array(entry_copy.frame_pos_odd.get_raw_data(), 14)); if (send_updates) - geomap_view->update_position(entry_copy.pos.latitude, entry_copy.pos.longitude); + geomap_view->update_position(entry_copy.pos.latitude, entry_copy.pos.longitude, entry_copy.velo.heading); } ADSBRxDetailsView::~ADSBRxDetailsView() { @@ -172,7 +172,7 @@ ADSBRxDetailsView::ADSBRxDetailsView( GeoPos::alt_unit::FEET, entry_copy.pos.latitude, entry_copy.pos.longitude, - 0, + entry_copy.velo.heading, [this]() { send_updates = false; }); @@ -214,6 +214,7 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) { if (frame.get_DF() == DF_ADSB) { uint8_t msg_type = frame.get_msg_type(); + uint8_t msg_sub = frame.get_msg_sub(); uint8_t * raw_data = frame.get_raw_data(); if ((msg_type >= 1) && (msg_type <= 4)) { @@ -236,6 +237,8 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) { if (send_updates) details_view->update(entry); } + } else if(msg_type == 19 && (msg_sub >= 1 && msg_sub <= 4)){ + entry.set_frame_velo(frame); } } recent_entries_view.set_dirty(); diff --git a/firmware/application/apps/ui_adsb_rx.hpp b/firmware/application/apps/ui_adsb_rx.hpp index c03166233..816992ee6 100644 --- a/firmware/application/apps/ui_adsb_rx.hpp +++ b/firmware/application/apps/ui_adsb_rx.hpp @@ -49,7 +49,7 @@ struct AircraftRecentEntry { uint16_t hits { 0 }; uint32_t age { 0 }; adsb_pos pos { false, 0, 0, 0 }; - + adsb_vel velo { false, 0, 0 }; ADSBFrame frame_pos_even { }; ADSBFrame frame_pos_odd { }; @@ -86,6 +86,10 @@ struct AircraftRecentEntry { pos = decode_frame_pos(frame_pos_even, frame_pos_odd); } } + + void set_frame_velo(ADSBFrame& frame){ + velo = decode_frame_velo(frame); + } void set_info_string(std::string& new_info_string) { info_string = new_info_string; diff --git a/firmware/application/ui/ui_geomap.cpp b/firmware/application/ui/ui_geomap.cpp index f907825a7..20da068e8 100644 --- a/firmware/application/ui/ui_geomap.cpp +++ b/firmware/application/ui/ui_geomap.cpp @@ -168,10 +168,15 @@ void GeoMap::paint(Painter& painter) { // Cross display.fill_rectangle({ r.center() - Point(16, 1), { 32, 2 } }, Color::red()); display.fill_rectangle({ r.center() - Point(1, 16), { 2, 32 } }, Color::red()); - } else { - draw_bearing(r.center(), angle_, 10, Color::red()); - //center tag above bearing - painter.draw_string(r.center() - Point(((int)tag_.length() * 8 / 2), 2 * 16), style(), tag_); + } else if (angle_ < 360){ + //if we have a valid angle just draw bearing + draw_bearing({ 120, 32 + 144 }, angle_, 10, Color::red()); + painter.draw_string({ 120 - ((int)tag_.length() * 8 / 2), 32 + 144 - 32 }, style(), tag_); + } + else { + //draw a small cross + display.fill_rectangle({ r.center() - Point(8, 1), { 16, 2 } }, Color::red()); + display.fill_rectangle({ r.center() - Point(1, 8), { 2, 16 } }, Color::red()); } } @@ -231,7 +236,7 @@ void GeoMap::set_mode(GeoMapMode mode) { mode_ = mode; } -void GeoMap::draw_bearing(const Point origin, const uint32_t angle, uint32_t size, const Color color) { +void GeoMap::draw_bearing(const Point origin, const uint16_t angle, uint32_t size, const Color color) { Point arrow_a, arrow_b, arrow_c; for (size_t thickness = 0; thickness < 3; thickness++) { @@ -254,9 +259,10 @@ void GeoMapView::focus() { nav_.display_modal("No map", "No world_map.bin file in\n/ADSB/ directory", ABORT, nullptr); } -void GeoMapView::update_position(float lat, float lon) { +void GeoMapView::update_position(float lat, float lon, uint16_t angle) { lat_ = lat; lon_ = lon; + angle_ = angle; geopos.set_lat(lat_); geopos.set_lon(lon_); geomap.move(lon_, lat_); @@ -307,7 +313,7 @@ GeoMapView::GeoMapView( GeoPos::alt_unit altitude_unit, float lat, float lon, - float angle, + uint16_t angle, const std::function on_close ) : nav_ (nav), altitude_ (altitude), diff --git a/firmware/application/ui/ui_geomap.hpp b/firmware/application/ui/ui_geomap.hpp index 45a9479b1..e4e5ebff9 100644 --- a/firmware/application/ui/ui_geomap.hpp +++ b/firmware/application/ui/ui_geomap.hpp @@ -130,7 +130,7 @@ public: } private: - void draw_bearing(const Point origin, const uint32_t angle, uint32_t size, const Color color); + void draw_bearing(const Point origin, const uint16_t angle, uint32_t size, const Color color); GeoMapMode mode_ { }; File map_file { }; @@ -141,7 +141,7 @@ private: int32_t prev_x_pos { 0xFFFF }, prev_y_pos { 0xFFFF }; float lat_ { }; float lon_ { }; - float angle_ { }; + uint16_t angle_ { }; std::string tag_ { }; }; @@ -154,7 +154,7 @@ public: GeoPos::alt_unit altitude_unit, float lat, float lon, - float angle, + uint16_t angle, const std::function on_close = nullptr ); GeoMapView(NavigationView& nav, @@ -173,7 +173,7 @@ public: void focus() override; - void update_position(float lat, float lon); + void update_position(float lat, float lon, uint16_t angle); std::string title() const override { return "Map view"; }; @@ -190,7 +190,7 @@ private: GeoPos::alt_unit altitude_unit_ { }; float lat_ { }; float lon_ { }; - float angle_ { }; + uint16_t angle_ { }; std::function on_close_ { nullptr }; bool map_opened { }; diff --git a/firmware/common/adsb.cpp b/firmware/common/adsb.cpp index c730bbecb..1831e89d7 100644 --- a/firmware/common/adsb.cpp +++ b/firmware/common/adsb.cpp @@ -300,8 +300,8 @@ void encode_frame_velo(ADSBFrame& frame, const uint32_t ICAO_address, const uint v_rate_coded = (v_rate / 64) + 1; - velo_ew_abs = abs(velo_ew); - velo_ns_abs = abs(velo_ns); + velo_ew_abs = abs(velo_ew) + 1; + velo_ns_abs = abs(velo_ns) + 1; v_rate_coded_abs = abs(v_rate_coded); make_frame_adsb(frame, ICAO_address); @@ -317,4 +317,47 @@ void encode_frame_velo(ADSBFrame& frame, const uint32_t ICAO_address, const uint frame.make_CRC(); } +// Decoding method from dump1090 +adsb_vel decode_frame_velo(ADSBFrame& frame){ + adsb_vel velo {false, 0, 0}; + + uint8_t * frame_data = frame.get_raw_data(); + uint8_t velo_type = frame.get_msg_sub(); + + if(velo_type >= 1 && velo_type <= 4){ //vertical rate is always present + + velo.v_rate = (((frame_data[8] & 0x07 ) << 6) | ((frame_data[9]) >> 2) - 1) * 64; + + if((frame_data[8] & 0x8) >> 3) velo.v_rate *= -1; //check v_rate sign + } + + if(velo_type == 1 || velo_type == 2){ //Ground Speed + int32_t velo_ew = (((frame_data[5] & 0x03) << 8) | frame_data[6]) - 1; + int32_t velo_ns = ((frame_data[7] & 0x7f) << 3) | ((frame_data[8]) >> 5) - 1; + + if (velo_type == 2){ // supersonic indicator so multiply by 4 + velo_ew = velo_ew << 2; + velo_ns = velo_ns << 2; + } + + if((frame_data[5]&4) >> 2) velo_ew *= -1; //check ew direction sign + if((frame_data[7]&0x80) >> 7) velo_ns *= -1; //check ns direction sign + + velo.speed = sqrt(velo_ns*velo_ns + velo_ew*velo_ew); + if(velo.speed){ + //calculate heading in degrees from ew/ns velocities + velo.heading = (uint16_t)(atan2(velo_ew,velo_ns) * 180.0 / pi); + // We don't want negative values but a 0-360 scale. + if (velo.heading < 0) velo.heading += 360.0; + } + + }else if(velo_type == 3 || velo_type == 4){ //Airspeed + velo.valid = frame_data[5] & (1<<2); + velo.heading = ((((frame_data[5] & 0x03)<<8) | frame_data[6]) * 45) << 7; + } + + return velo; + +} + } /* namespace adsb */ diff --git a/firmware/common/adsb.hpp b/firmware/common/adsb.hpp index 4e042ff21..82d177e49 100644 --- a/firmware/common/adsb.hpp +++ b/firmware/common/adsb.hpp @@ -56,6 +56,13 @@ struct adsb_pos { int32_t altitude; }; +struct adsb_vel { + bool valid; + int32_t speed; //knot + uint16_t heading; //degree + int32_t v_rate; //ft/min +}; + const float CPR_MAX_VALUE = 131072.0; const float adsb_lat_lut[58] = { @@ -89,6 +96,8 @@ adsb_pos decode_frame_pos(ADSBFrame& frame_even, ADSBFrame& frame_odd); void encode_frame_velo(ADSBFrame& frame, const uint32_t ICAO_address, const uint32_t speed, const float angle, const int32_t v_rate); +adsb_vel decode_frame_velo(ADSBFrame& frame); + //void encode_frame_emergency(ADSBFrame& frame, const uint32_t ICAO_address, const uint8_t code); void encode_frame_squawk(ADSBFrame& frame, const uint32_t squawk); diff --git a/firmware/common/adsb_frame.hpp b/firmware/common/adsb_frame.hpp index 36685843d..a93abe6fb 100644 --- a/firmware/common/adsb_frame.hpp +++ b/firmware/common/adsb_frame.hpp @@ -41,6 +41,10 @@ public: return (raw_data[4] >> 3); } + uint8_t get_msg_sub() { + return (raw_data[4] & 7); + } + uint32_t get_ICAO_address() { return (raw_data[1] << 16) + (raw_data[2] << 8) + raw_data[3]; } From ea574ef61f244e7ee8a057effd2d2772a3c6131c Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Fri, 24 Jul 2020 16:10:57 -0500 Subject: [PATCH 02/12] Set Sonde heading out of bounds --- firmware/application/apps/ui_sonde.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/apps/ui_sonde.cpp b/firmware/application/apps/ui_sonde.cpp index 16506b3f1..c08ff6427 100644 --- a/firmware/application/apps/ui_sonde.cpp +++ b/firmware/application/apps/ui_sonde.cpp @@ -91,7 +91,7 @@ SondeView::SondeView(NavigationView& nav) { GeoPos::alt_unit::METERS, latitude, longitude, - 0); + 999); //set a dummy heading out of range to draw a cross...probably not ideal? }; logger = std::make_unique(); From 62df30eae3988f9e987b21d69157ebafc2cc9de3 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Fri, 24 Jul 2020 18:56:09 -0500 Subject: [PATCH 03/12] add heading information to adsb details view --- firmware/application/apps/ui_adsb_rx.cpp | 7 +++++-- firmware/application/apps/ui_adsb_rx.hpp | 6 ++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index 8a174e4cf..c44868af9 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -92,7 +92,7 @@ void ADSBRxDetailsView::update(const AircraftRecentEntry& entry) { text_last_seen.set(to_string_dec_uint(age / 60) + " minutes ago"); text_infos.set(entry_copy.info_string); - + text_info2.set("Hdg:" + to_string_dec_uint(entry_copy.velo.heading)); text_frame_pos_even.set(to_string_hex_array(entry_copy.frame_pos_even.get_raw_data(), 14)); text_frame_pos_odd.set(to_string_hex_array(entry_copy.frame_pos_odd.get_raw_data(), 14)); @@ -123,6 +123,7 @@ ADSBRxDetailsView::ADSBRxDetailsView( &text_airline, &text_country, &text_infos, + &text_info2, &text_frame_pos_even, &text_frame_pos_odd, &button_see_map @@ -237,8 +238,10 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) { if (send_updates) details_view->update(entry); } - } else if(msg_type == 19 && (msg_sub >= 1 && msg_sub <= 4)){ + } else if(msg_type == 19 && msg_sub >= 1 && msg_sub <= 4){ entry.set_frame_velo(frame); + if (send_updates) + 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 816992ee6..6964aa9b5 100644 --- a/firmware/application/apps/ui_adsb_rx.hpp +++ b/firmware/application/apps/ui_adsb_rx.hpp @@ -178,6 +178,12 @@ private: { 0 * 8, 6 * 16, 30 * 8, 16 }, "-" }; + + Text text_info2 { + {0*8, 7*16, 30*8, 16}, + "-" + }; + Text text_frame_pos_even { { 0 * 8, 13 * 16, 30 * 8, 16 }, "-" From 542879b74bd30a51e1c43f90a19fb3079365e19b Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sat, 25 Jul 2020 10:21:56 -0500 Subject: [PATCH 04/12] allow negative heading in maths --- firmware/common/adsb.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/firmware/common/adsb.cpp b/firmware/common/adsb.cpp index 1831e89d7..6a4412fec 100644 --- a/firmware/common/adsb.cpp +++ b/firmware/common/adsb.cpp @@ -344,11 +344,13 @@ adsb_vel decode_frame_velo(ADSBFrame& frame){ if((frame_data[7]&0x80) >> 7) velo_ns *= -1; //check ns direction sign velo.speed = sqrt(velo_ns*velo_ns + velo_ew*velo_ew); + if(velo.speed){ //calculate heading in degrees from ew/ns velocities - velo.heading = (uint16_t)(atan2(velo_ew,velo_ns) * 180.0 / pi); + int16_t heading_temp = (int16_t)(atan2(velo_ew,velo_ns) * 180.0 / pi); // We don't want negative values but a 0-360 scale. - if (velo.heading < 0) velo.heading += 360.0; + if (heading_temp < 0) heading_temp += 360.0; + velo.heading = (uint16_t)heading_temp; } }else if(velo_type == 3 || velo_type == 4){ //Airspeed From f32584c553c635daa23fbae7eb547530136c471e Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sat, 25 Jul 2020 10:22:21 -0500 Subject: [PATCH 05/12] Add heading and speed to detail view --- firmware/application/apps/ui_adsb_rx.cpp | 8 ++++++-- firmware/application/apps/ui_adsb_rx.hpp | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index c44868af9..1fff7e07d 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -92,7 +92,11 @@ void ADSBRxDetailsView::update(const AircraftRecentEntry& entry) { text_last_seen.set(to_string_dec_uint(age / 60) + " minutes ago"); text_infos.set(entry_copy.info_string); - text_info2.set("Hdg:" + to_string_dec_uint(entry_copy.velo.heading)); + if(entry_copy.velo.heading < 360 && entry_copy.velo.speed >=0){ //I don't like this but... + text_info2.set("Hdg:" + to_string_dec_uint(entry_copy.velo.heading) + " Spd:" + to_string_dec_int(entry_copy.velo.speed)); + }else{ + text_info2.set(""); + } text_frame_pos_even.set(to_string_hex_array(entry_copy.frame_pos_even.get_raw_data(), 14)); text_frame_pos_odd.set(to_string_hex_array(entry_copy.frame_pos_odd.get_raw_data(), 14)); @@ -200,7 +204,7 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) { auto frame = message->frame; uint32_t ICAO_address = frame.get_ICAO_address(); - + if (frame.check_CRC() && frame.get_ICAO_address()) { rtcGetTime(&RTCD1, &datetime); auto& entry = ::on_packet(recent, ICAO_address); diff --git a/firmware/application/apps/ui_adsb_rx.hpp b/firmware/application/apps/ui_adsb_rx.hpp index 6964aa9b5..55d590bdd 100644 --- a/firmware/application/apps/ui_adsb_rx.hpp +++ b/firmware/application/apps/ui_adsb_rx.hpp @@ -49,7 +49,7 @@ struct AircraftRecentEntry { uint16_t hits { 0 }; uint32_t age { 0 }; adsb_pos pos { false, 0, 0, 0 }; - adsb_vel velo { false, 0, 0 }; + adsb_vel velo { false, 0, 999 }; ADSBFrame frame_pos_even { }; ADSBFrame frame_pos_odd { }; From 3ec41bc20957eab08d9daa97430b3ee7af725355 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sat, 25 Jul 2020 10:23:46 -0500 Subject: [PATCH 06/12] Fix angle updating and remove empty callsign --- firmware/application/ui/ui_geomap.cpp | 13 ++++++++----- firmware/application/ui/ui_geomap.hpp | 4 ++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/firmware/application/ui/ui_geomap.cpp b/firmware/application/ui/ui_geomap.cpp index 20da068e8..88d8b2096 100644 --- a/firmware/application/ui/ui_geomap.cpp +++ b/firmware/application/ui/ui_geomap.cpp @@ -59,7 +59,7 @@ GeoPos::GeoPos( set_altitude(0); set_lat(0); set_lon(0); - + const auto changed_fn = [this](int32_t) { float lat_value = lat(); float lon_value = lon(); @@ -169,9 +169,11 @@ void GeoMap::paint(Painter& painter) { display.fill_rectangle({ r.center() - Point(16, 1), { 32, 2 } }, Color::red()); display.fill_rectangle({ r.center() - Point(1, 16), { 2, 32 } }, Color::red()); } else if (angle_ < 360){ - //if we have a valid angle just draw bearing + //if we have a valid angle draw bearing draw_bearing({ 120, 32 + 144 }, angle_, 10, Color::red()); - painter.draw_string({ 120 - ((int)tag_.length() * 8 / 2), 32 + 144 - 32 }, style(), tag_); + if(tag_.find_first_not_of(' ') != tag_.npos){ //only draw tag if we have something other than spaces + painter.draw_string({ 120 - ((int)tag_.length() * 8 / 2), 32 + 144 - 32 }, style(), tag_); + } } else { //draw a small cross @@ -262,9 +264,9 @@ void GeoMapView::focus() { void GeoMapView::update_position(float lat, float lon, uint16_t angle) { lat_ = lat; lon_ = lon; - angle_ = angle; geopos.set_lat(lat_); geopos.set_lon(lon_); + geomap.set_angle(angle); geomap.move(lon_, lat_); geomap.set_dirty(); } @@ -275,7 +277,7 @@ void GeoMapView::setup() { geopos.set_altitude(altitude_); geopos.set_lat(lat_); geopos.set_lon(lon_); - + geopos.on_change = [this](int32_t altitude, float lat, float lon) { altitude_ = altitude; lat_ = lat; @@ -334,6 +336,7 @@ GeoMapView::GeoMapView( geomap.set_mode(mode_); geomap.set_tag(tag); + geomap.set_angle(angle); geomap.move(lon_, lat_); geopos.set_read_only(true); diff --git a/firmware/application/ui/ui_geomap.hpp b/firmware/application/ui/ui_geomap.hpp index e4e5ebff9..30fd69830 100644 --- a/firmware/application/ui/ui_geomap.hpp +++ b/firmware/application/ui/ui_geomap.hpp @@ -129,6 +129,10 @@ public: tag_ = new_tag; } + void set_angle(uint16_t new_angle){ + angle_ = new_angle; + } + private: void draw_bearing(const Point origin, const uint16_t angle, uint32_t size, const Color color); From 01101ecef20c71f33d861822739e0ed0871b3578 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sat, 25 Jul 2020 12:26:10 -0500 Subject: [PATCH 07/12] position string formatting --- firmware/application/apps/ui_adsb_rx.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index 1fff7e07d..52c557561 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -231,9 +231,9 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) { if (entry.pos.valid) { str_info = "Alt:" + to_string_dec_uint(entry.pos.altitude) + - " Lat" + to_string_dec_int(entry.pos.latitude) + + " Lat:" + to_string_dec_int(entry.pos.latitude) + "." + to_string_dec_int((int)abs(entry.pos.latitude * 1000) % 100, 2, '0') + - " Lon" + to_string_dec_int(entry.pos.longitude) + + " Lon:" + to_string_dec_int(entry.pos.longitude) + "." + to_string_dec_int((int)abs(entry.pos.longitude * 1000) % 100, 2, '0'); entry.set_info_string(str_info); From 4c256f65dd952c0e860cbb5e72df8349996d4ebe Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sat, 25 Jul 2020 12:48:47 -0500 Subject: [PATCH 08/12] Re-add bearing position fix --- firmware/application/ui/ui_geomap.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/firmware/application/ui/ui_geomap.cpp b/firmware/application/ui/ui_geomap.cpp index 88d8b2096..d793c223e 100644 --- a/firmware/application/ui/ui_geomap.cpp +++ b/firmware/application/ui/ui_geomap.cpp @@ -170,9 +170,10 @@ void GeoMap::paint(Painter& painter) { display.fill_rectangle({ r.center() - Point(1, 16), { 2, 32 } }, Color::red()); } else if (angle_ < 360){ //if we have a valid angle draw bearing - draw_bearing({ 120, 32 + 144 }, angle_, 10, Color::red()); + draw_bearing(r.center(), angle_, 10, Color::red()); + //center tag above bearing if(tag_.find_first_not_of(' ') != tag_.npos){ //only draw tag if we have something other than spaces - painter.draw_string({ 120 - ((int)tag_.length() * 8 / 2), 32 + 144 - 32 }, style(), tag_); + painter.draw_string(r.center() - Point(((int)tag_.length() * 8 / 2), 2 * 16), style(), tag_); } } else { From bbae5047d19d5cc8b7727b20ea80db7f7b5b2c3f Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Mon, 10 Aug 2020 22:55:20 -0500 Subject: [PATCH 09/12] Fix ADSB heading math and add heading to ADSB log --- firmware/application/apps/ui_adsb_rx.cpp | 3 +++ firmware/common/adsb.cpp | 11 +++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index 52c557561..bd158620d 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -244,6 +244,9 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) { } } else if(msg_type == 19 && msg_sub >= 1 && msg_sub <= 4){ 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) details_view->update(entry); } diff --git a/firmware/common/adsb.cpp b/firmware/common/adsb.cpp index 6a4412fec..3f8f4c231 100644 --- a/firmware/common/adsb.cpp +++ b/firmware/common/adsb.cpp @@ -332,16 +332,19 @@ adsb_vel decode_frame_velo(ADSBFrame& frame){ } if(velo_type == 1 || velo_type == 2){ //Ground Speed - int32_t velo_ew = (((frame_data[5] & 0x03) << 8) | frame_data[6]) - 1; - int32_t velo_ns = ((frame_data[7] & 0x7f) << 3) | ((frame_data[8]) >> 5) - 1; + int32_t raw_ew = ((frame_data[5] & 0x03) << 8) | frame_data[6]; + int32_t velo_ew = raw_ew - 1; //velocities are all offset by one (this is part of the spec) + + int32_t raw_ns = ((frame_data[7] & 0x7f) << 3) | (frame_data[8] >> 5); + int32_t velo_ns = raw_ns - 1; if (velo_type == 2){ // supersonic indicator so multiply by 4 velo_ew = velo_ew << 2; velo_ns = velo_ns << 2; } - if((frame_data[5]&4) >> 2) velo_ew *= -1; //check ew direction sign - if((frame_data[7]&0x80) >> 7) velo_ns *= -1; //check ns direction sign + if(frame_data[5]&0x04) velo_ew *= -1; //check ew direction sign + if(frame_data[7]&0x80) velo_ns *= -1; //check ns direction sign velo.speed = sqrt(velo_ns*velo_ns + velo_ew*velo_ew); From 13ba70f6c574ecc9bdd2481a81c6a1a2016a2c3f Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Tue, 11 Aug 2020 11:26:36 -0500 Subject: [PATCH 10/12] Fix negative altitude on DetailsView --- firmware/application/apps/ui_adsb_rx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index bd158620d..ba0804812 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -230,7 +230,7 @@ void ADSBRxView::on_frame(const ADSBFrameMessage * message) { entry.set_frame_pos(frame, raw_data[6] & 4); if (entry.pos.valid) { - str_info = "Alt:" + to_string_dec_uint(entry.pos.altitude) + + str_info = "Alt:" + to_string_dec_int(entry.pos.altitude) + " Lat:" + to_string_dec_int(entry.pos.latitude) + "." + to_string_dec_int((int)abs(entry.pos.latitude * 1000) % 100, 2, '0') + " Lon:" + to_string_dec_int(entry.pos.longitude) + From f6437adc60af56d0c9f94f8d8d66a593f0d2f1ae Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Tue, 11 Aug 2020 11:26:54 -0500 Subject: [PATCH 11/12] Reorganixe ADSBDetailsView --- firmware/application/apps/ui_adsb_rx.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/firmware/application/apps/ui_adsb_rx.hpp b/firmware/application/apps/ui_adsb_rx.hpp index 55d590bdd..dd7adb5a5 100644 --- a/firmware/application/apps/ui_adsb_rx.hpp +++ b/firmware/application/apps/ui_adsb_rx.hpp @@ -150,8 +150,8 @@ private: { { 0 * 8, 2 * 16 }, "Last seen:", Color::light_grey() }, { { 0 * 8, 3 * 16 }, "Airline:", Color::light_grey() }, { { 0 * 8, 5 * 16 }, "Country:", Color::light_grey() }, - { { 0 * 8, 12 * 16 }, "Even position frame:", Color::light_grey() }, - { { 0 * 8, 14 * 16 }, "Odd position frame:", Color::light_grey() } + { { 0 * 8, 13 * 16 }, "Even position frame:", Color::light_grey() }, + { { 0 * 8, 15 * 16 }, "Odd position frame:", Color::light_grey() } }; Text text_callsign { @@ -185,16 +185,16 @@ private: }; Text text_frame_pos_even { - { 0 * 8, 13 * 16, 30 * 8, 16 }, + { 0 * 8, 14 * 16, 30 * 8, 16 }, "-" }; Text text_frame_pos_odd { - { 0 * 8, 15 * 16, 30 * 8, 16 }, + { 0 * 8, 16 * 16, 30 * 8, 16 }, "-" }; Button button_see_map { - { 8 * 8, 8 * 16, 14 * 8, 3 * 16 }, + { 8 * 8, 9 * 16, 14 * 8, 3 * 16 }, "See on map" }; }; From 27a549dac76d42750634a79128893c3f33f73f07 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Fri, 14 Aug 2020 15:46:45 -0500 Subject: [PATCH 12/12] allow printing tag even without a valid heading --- firmware/application/ui/ui_geomap.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/firmware/application/ui/ui_geomap.cpp b/firmware/application/ui/ui_geomap.cpp index d793c223e..91fcb545e 100644 --- a/firmware/application/ui/ui_geomap.cpp +++ b/firmware/application/ui/ui_geomap.cpp @@ -163,7 +163,10 @@ void GeoMap::paint(Painter& painter) { prev_x_pos = x_pos; prev_y_pos = y_pos; } - + //center tag above point + if(tag_.find_first_not_of(' ') != tag_.npos){ //only draw tag if we have something other than spaces + painter.draw_string(r.center() - Point(((int)tag_.length() * 8 / 2), 2 * 16), style(), tag_); + } if (mode_ == PROMPT) { // Cross display.fill_rectangle({ r.center() - Point(16, 1), { 32, 2 } }, Color::red()); @@ -171,10 +174,6 @@ void GeoMap::paint(Painter& painter) { } else if (angle_ < 360){ //if we have a valid angle draw bearing draw_bearing(r.center(), angle_, 10, Color::red()); - //center tag above bearing - if(tag_.find_first_not_of(' ') != tag_.npos){ //only draw tag if we have something other than spaces - painter.draw_string(r.center() - Point(((int)tag_.length() * 8 / 2), 2 * 16), style(), tag_); - } } else { //draw a small cross