diff --git a/firmware/application/apps/ais_app.cpp b/firmware/application/apps/ais_app.cpp index d8dc4637..74f4183b 100644 --- a/firmware/application/apps/ais_app.cpp +++ b/firmware/application/apps/ais_app.cpp @@ -293,6 +293,7 @@ AISRecentEntryDetailView::AISRecentEntryDetailView(NavigationView& nav) { ais::format::text(entry_.name), 0, GeoPos::alt_unit::METERS, + GeoPos::spd_unit::NONE, ais::format::latlon_float(entry_.last_position.latitude.normalized()), ais::format::latlon_float(entry_.last_position.longitude.normalized()), entry_.last_position.true_heading, @@ -315,7 +316,7 @@ AISRecentEntryDetailView& AISRecentEntryDetailView::operator=(const AISRecentEnt 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()), (float)entry_.last_position.true_heading, 0); + 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, 0, entry_.last_position.speed_over_ground); } void AISRecentEntryDetailView::focus() { diff --git a/firmware/application/apps/ui_adsb_rx.cpp b/firmware/application/apps/ui_adsb_rx.cpp index adaa42c7..2279427b 100644 --- a/firmware/application/apps/ui_adsb_rx.cpp +++ b/firmware/application/apps/ui_adsb_rx.cpp @@ -266,6 +266,7 @@ ADSBRxDetailsView::ADSBRxDetailsView( get_map_tag(entry_), entry_.pos.altitude, GeoPos::alt_unit::FEET, + GeoPos::spd_unit::MPH, entry_.pos.latitude, entry_.pos.longitude, entry_.velo.heading); @@ -290,7 +291,7 @@ void ADSBRxDetailsView::update(const AircraftRecentEntry& entry) { } else if (geomap_view_) { // Map is showing, update the current item. geomap_view_->update_tag(get_map_tag(entry_)); - geomap_view_->update_position(entry.pos.latitude, entry.pos.longitude, entry.velo.heading, entry.pos.altitude); + geomap_view_->update_position(entry.pos.latitude, entry.pos.longitude, entry.velo.heading, entry.pos.altitude, entry.velo.speed); } else { // Details is showing, update details. refresh_ui(); diff --git a/firmware/application/apps/ui_adsb_tx.cpp b/firmware/application/apps/ui_adsb_tx.cpp index 4104bbf0..4cc0b79a 100644 --- a/firmware/application/apps/ui_adsb_tx.cpp +++ b/firmware/application/apps/ui_adsb_tx.cpp @@ -85,10 +85,12 @@ ADSBPositionView::ADSBPositionView( nav.push( geopos.altitude(), GeoPos::alt_unit::FEET, + GeoPos::spd_unit::HIDDEN, geopos.lat(), geopos.lon(), - [this](int32_t altitude, float lat, float lon) { + [this](int32_t altitude, float lat, float lon, int32_t speed) { geopos.set_altitude(altitude); + geopos.set_speed(speed); geopos.set_lat(lat); geopos.set_lon(lon); }); diff --git a/firmware/application/apps/ui_adsb_tx.hpp b/firmware/application/apps/ui_adsb_tx.hpp index 18e72537..873d1e14 100644 --- a/firmware/application/apps/ui_adsb_tx.hpp +++ b/firmware/application/apps/ui_adsb_tx.hpp @@ -58,7 +58,8 @@ class ADSBPositionView : public OptionTabView { private: GeoPos geopos{ {0, 2 * 16}, - GeoPos::FEET}; + GeoPos::FEET, + GeoPos::HIDDEN}; Button button_set_map{ {8 * 8, 6 * 16, 14 * 8, 2 * 16}, diff --git a/firmware/application/apps/ui_aprs_rx.cpp b/firmware/application/apps/ui_aprs_rx.cpp index e2c6e759..a703555a 100644 --- a/firmware/application/apps/ui_aprs_rx.cpp +++ b/firmware/application/apps/ui_aprs_rx.cpp @@ -317,7 +317,7 @@ void APRSDetailsView::update() { } if (send_updates) - geomap_view->update_position(entry_copy.pos.latitude, entry_copy.pos.longitude, 0, 0); + geomap_view->update_position(entry_copy.pos.latitude, entry_copy.pos.longitude, 0, 0, 0); } APRSDetailsView::~APRSDetailsView() { @@ -339,6 +339,7 @@ APRSDetailsView::APRSDetailsView( entry_copy.source_formatted, 0, // entry_copy.pos.altitude, GeoPos::alt_unit::FEET, + GeoPos::spd_unit::HIDDEN, entry_copy.pos.latitude, entry_copy.pos.longitude, 0, /*entry_copy.velo.heading,*/ diff --git a/firmware/application/apps/ui_sonde.cpp b/firmware/application/apps/ui_sonde.cpp index b6e975c7..b809e591 100644 --- a/firmware/application/apps/ui_sonde.cpp +++ b/firmware/application/apps/ui_sonde.cpp @@ -94,6 +94,7 @@ SondeView::SondeView(NavigationView& nav) sonde_id, gps_info.alt, GeoPos::alt_unit::METERS, + GeoPos::spd_unit::HIDDEN, gps_info.lat, gps_info.lon, 999); // set a dummy heading out of range to draw a cross...probably not ideal? diff --git a/firmware/application/apps/ui_sonde.hpp b/firmware/application/apps/ui_sonde.hpp index d3992fd4..d93b90be 100644 --- a/firmware/application/apps/ui_sonde.hpp +++ b/firmware/application/apps/ui_sonde.hpp @@ -162,7 +162,8 @@ class SondeView : public View { GeoPos geopos{ {0, 12 * 16}, - GeoPos::alt_unit::METERS}; + GeoPos::alt_unit::METERS, + GeoPos::spd_unit::HIDDEN}; Button button_see_qr{ {2 * 8, 15 * 16, 12 * 8, 3 * 16}, diff --git a/firmware/application/ui/ui_geomap.cpp b/firmware/application/ui/ui_geomap.cpp index b3046f97..71cf6279 100644 --- a/firmware/application/ui/ui_geomap.cpp +++ b/firmware/application/ui/ui_geomap.cpp @@ -38,13 +38,17 @@ namespace ui { GeoPos::GeoPos( const Point pos, - const alt_unit altitude_unit) - : altitude_unit_(altitude_unit) { + const alt_unit altitude_unit, + const spd_unit speed_unit) + : altitude_unit_(altitude_unit), speed_unit_(speed_unit) { set_parent_rect({pos, {30 * 8, 3 * 16}}); add_children({&labels_position, + &label_spd_position, &field_altitude, + &field_speed, &text_alt_unit, + &text_speed_unit, &field_lat_degrees, &field_lat_minutes, &field_lat_seconds, @@ -56,6 +60,7 @@ GeoPos::GeoPos( // Defaults set_altitude(0); + set_speed(0); set_lat(0); set_lon(0); @@ -67,10 +72,11 @@ GeoPos::GeoPos( text_lon_decimal.set(to_string_decimal(lon_value, 5)); if (on_change && report_change) - on_change(altitude(), lat_value, lon_value); + on_change(altitude(), lat_value, lon_value, speed()); }; field_altitude.on_change = changed_fn; + field_speed.on_change = changed_fn; field_lat_degrees.on_change = changed_fn; field_lat_minutes.on_change = changed_fn; field_lat_seconds.on_change = changed_fn; @@ -79,11 +85,19 @@ GeoPos::GeoPos( field_lon_seconds.on_change = changed_fn; text_alt_unit.set(altitude_unit_ ? "m" : "ft"); + if (speed_unit_ == KMPH) text_speed_unit.set("kmph"); + if (speed_unit_ == MPH) text_speed_unit.set("mph"); + if (speed_unit_ == HIDDEN) { + text_speed_unit.hidden(true); + label_spd_position.hidden(true); + field_speed.hidden(true); + } } void GeoPos::set_read_only(bool v) { // only setting altitude to read-only (allow manual panning via lat/lon fields) field_altitude.set_focusable(!v); + field_speed.set_focusable(!v); } // Stupid hack to avoid an event loop @@ -98,14 +112,18 @@ void GeoPos::focus() { field_lat_degrees.focus(); } -void GeoPos::hide_altitude() { +void GeoPos::hide_altandspeed() { // Color altitude grey to indicate it's not updated in manual panning mode field_altitude.set_style(&Styles::grey); + field_speed.set_style(&Styles::grey); } void GeoPos::set_altitude(int32_t altitude) { field_altitude.set_value(altitude); } +void GeoPos::set_speed(int32_t speed) { + field_speed.set_value(speed); +} void GeoPos::set_lat(float lat) { field_lat_degrees.set_value(lat); @@ -139,6 +157,10 @@ int32_t GeoPos::altitude() { return field_altitude.value(); }; +int32_t GeoPos::speed() { + return field_speed.value(); +}; + GeoMap::GeoMap( Rect parent_rect) : Widget{parent_rect}, markerListLen(0) { @@ -458,7 +480,7 @@ void GeoMapView::focus() { nav_.display_modal("No map", "No world_map.bin file in\n/ADSB/ directory", ABORT); } -void GeoMapView::update_position(float lat, float lon, uint16_t angle, int32_t altitude) { +void GeoMapView::update_position(float lat, float lon, uint16_t angle, int32_t altitude, int32_t speed) { if (geomap.manual_panning()) { geomap.set_dirty(); return; @@ -467,12 +489,14 @@ void GeoMapView::update_position(float lat, float lon, uint16_t angle, int32_t a lat_ = lat; lon_ = lon; altitude_ = altitude; + speed_ = speed; // Stupid hack to avoid an event loop geopos.set_report_change(false); geopos.set_lat(lat_); geopos.set_lon(lon_); geopos.set_altitude(altitude_); + geopos.set_speed(speed_); geopos.set_report_change(true); geomap.set_angle(angle); @@ -491,11 +515,12 @@ void GeoMapView::setup() { geopos.set_lat(lat_); geopos.set_lon(lon_); - geopos.on_change = [this](int32_t altitude, float lat, float lon) { + geopos.on_change = [this](int32_t altitude, float lat, float lon, int32_t speed) { altitude_ = altitude; lat_ = lat; lon_ = lon; - geopos.hide_altitude(); + speed_ = speed; + geopos.hide_altandspeed(); geomap.set_manual_panning(true); geomap.move(lon_, lat_); geomap.set_dirty(); @@ -527,6 +552,7 @@ GeoMapView::GeoMapView( const std::string& tag, int32_t altitude, GeoPos::alt_unit altitude_unit, + GeoPos::spd_unit speed_unit, float lat, float lon, uint16_t angle, @@ -534,6 +560,7 @@ GeoMapView::GeoMapView( : nav_(nav), altitude_(altitude), altitude_unit_(altitude_unit), + speed_unit_(speed_unit), lat_(lat), lon_(lon), angle_(angle), @@ -561,12 +588,14 @@ GeoMapView::GeoMapView( NavigationView& nav, int32_t altitude, GeoPos::alt_unit altitude_unit, + GeoPos::spd_unit speed_unit, float lat, float lon, - const std::function on_done) + const std::function on_done) : nav_(nav), altitude_(altitude), altitude_unit_(altitude_unit), + speed_unit_(speed_unit), lat_(lat), lon_(lon) { mode_ = PROMPT; @@ -585,7 +614,7 @@ GeoMapView::GeoMapView( button_ok.on_select = [this, on_done, &nav](Button&) { if (on_done) - on_done(altitude_, lat_, lon_); + on_done(altitude_, lat_, lon_, speed_); nav.pop(); }; } diff --git a/firmware/application/ui/ui_geomap.hpp b/firmware/application/ui/ui_geomap.hpp index a59abe97..bb5bc586 100644 --- a/firmware/application/ui/ui_geomap.hpp +++ b/firmware/application/ui/ui_geomap.hpp @@ -62,19 +62,27 @@ class GeoPos : public View { FEET = 0, METERS }; + enum spd_unit { + NONE = 0, + MPH, + KMPH, + HIDDEN = 255 + }; - std::function on_change{}; + std::function on_change{}; - GeoPos(const Point pos, const alt_unit altitude_unit); + GeoPos(const Point pos, const alt_unit altitude_unit, const spd_unit speed_unit); void focus() override; void set_read_only(bool v); void set_altitude(int32_t altitude); + void set_speed(int32_t speed); void set_lat(float lat); void set_lon(float lon); int32_t altitude(); - void hide_altitude(); + int32_t speed(); + void hide_altandspeed(); float lat(); float lon(); @@ -84,22 +92,35 @@ class GeoPos : public View { bool read_only{false}; bool report_change{true}; alt_unit altitude_unit_{}; + spd_unit speed_unit_{}; Labels labels_position{ {{1 * 8, 0 * 16}, "Alt:", Color::light_grey()}, {{1 * 8, 1 * 16}, "Lat: \xB0 ' \"", Color::light_grey()}, // 0xB0 is degree ° symbol in our 8x16 font {{1 * 8, 2 * 16}, "Lon: \xB0 ' \"", Color::light_grey()}, }; - + Labels label_spd_position{ + {{15 * 8, 0 * 16}, "Spd:", Color::light_grey()}, + }; NumberField field_altitude{ {6 * 8, 0 * 16}, 5, {-1000, 50000}, 250, ' '}; + + NumberField field_speed{ + {19 * 8, 0 * 16}, + 4, + {0, 5000}, + 1, + ' '}; Text text_alt_unit{ {12 * 8, 0 * 16, 2 * 8, 16}, ""}; + Text text_speed_unit{ + {25 * 8, 0 * 16, 4 * 8, 16}, + ""}; NumberField field_lat_degrees{ {5 * 8, 1 * 16}, @@ -224,6 +245,7 @@ class GeoMapView : public View { const std::string& tag, int32_t altitude, GeoPos::alt_unit altitude_unit, + GeoPos::spd_unit speed_unit, float lat, float lon, uint16_t angle, @@ -231,9 +253,10 @@ class GeoMapView : public View { GeoMapView(NavigationView& nav, int32_t altitude, GeoPos::alt_unit altitude_unit, + GeoPos::spd_unit speed_unit, float lat, float lon, - const std::function on_done); + const std::function on_done); ~GeoMapView(); GeoMapView(const GeoMapView&) = delete; @@ -243,7 +266,7 @@ class GeoMapView : public View { void focus() override; - void update_position(float lat, float lon, uint16_t angle, int32_t altitude); + void update_position(float lat, float lon, uint16_t angle, int32_t altitude, int32_t speed = 0); std::string title() const override { return "Map view"; }; @@ -257,10 +280,12 @@ class GeoMapView : public View { void setup(); - const std::function on_done{}; + const std::function on_done{}; GeoMapMode mode_{}; int32_t altitude_{}; + int32_t speed_{}; GeoPos::alt_unit altitude_unit_{}; + GeoPos::spd_unit speed_unit_{}; float lat_{}; float lon_{}; uint16_t angle_{}; @@ -270,7 +295,8 @@ class GeoMapView : public View { GeoPos geopos{ {0, 0}, - altitude_unit_}; + altitude_unit_, + speed_unit_}; GeoMap geomap{ {0, GeoMap::banner_height, GeoMap::geomap_rect_width, GeoMap::geomap_rect_height}};