Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ constexpr double kDefaultRadarLon = 4.9041;

/** Poll adsb.fi (API public limit: 1 req/s). */
constexpr unsigned long kAdsbFetchIntervalMs = 3000;
/** Legacy scale unused — fetch uses radar::fetchRadiusKm() to screen edge. */
constexpr float kAdsbFetchRadiusScale = 1.0f;
/** false = hide aircraft with alt_baro "ground"; true = show them too. */
constexpr bool kAdsbShowGroundAircraft = false;

Expand Down
3 changes: 3 additions & 0 deletions include/services/adsb_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ void setPollFn(PollFn fn);
/** Fetch aircraft within fetch_radius_km of center_lat/lon from adsb.fi. */
bool fetchUpdate(double center_lat, double center_lon, float fetch_radius_km);

/** millis() of the last successful fetch (0 = never). */
unsigned long lastSuccessMs();

} // namespace services::adsb
1 change: 0 additions & 1 deletion include/ui/radar_range.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ void rangeInit();
/** Cycle preset and save to flash. */
void rangeNext();
const RangePreset& rangeCurrent();
uint8_t rangeIndex();
/** ADSB fetch radius (km): scaled to screen edge so beyond-ring dots have data. */
float fetchRadiusKm();

Expand Down
12 changes: 8 additions & 4 deletions src/services/adsb_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ constexpr unsigned long kRequestTimeoutMs = 10000;
Aircraft s_aircraft[kMaxAircraft];
size_t s_aircraft_count = 0;
PollFn s_poll_fn = nullptr;
unsigned long s_last_success_ms = 0;

void pollNetwork() {
if (s_poll_fn != nullptr) {
Expand All @@ -30,8 +31,8 @@ void pollNetwork() {

int performGetWithPoll(HTTPClient& http) {
http.setConnectTimeout(kConnectAttemptMs);
const unsigned long deadline = millis() + kRequestTimeoutMs;
while (millis() < deadline) {
const unsigned long start = millis();
while (millis() - start < kRequestTimeoutMs) {
pollNetwork();
const int code = http.GET();
if (code > 0) {
Expand All @@ -58,8 +59,8 @@ bool readResponseBodyWithPoll(HTTPClient& http, String& payload) {
}

uint8_t buffer[512];
const unsigned long deadline = millis() + kRequestTimeoutMs;
while (millis() < deadline) {
const unsigned long start = millis();
while (millis() - start < kRequestTimeoutMs) {
pollNetwork();
const int available = stream->available();
if (available > 0) {
Expand Down Expand Up @@ -276,8 +277,11 @@ bool fetchUpdate(double center_lat, double center_lon, float fetch_radius_km) {
}

s_aircraft_count = n;
s_last_success_ms = millis();
Serial.printf("adsb: %u aircraft\n", static_cast<unsigned>(n));
return true;
}

unsigned long lastSuccessMs() { return s_last_success_ms; }

} // namespace services::adsb
33 changes: 9 additions & 24 deletions src/ui/radar_display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ const lgfx::GFXfont* s_tag_gfx = &fonts::FreeSansBold12pt7b;
bool s_tag_label_metrics_ready = false;
bool s_tag_use_vlw = false;

int s_scale_label_max_w = 0;
int s_scale_label_h = 0;

lgfx::LovyanGFX* s_draw = &tft;
LGFX_Sprite s_frame(&tft);
bool s_frame_ready = false;
Expand Down Expand Up @@ -135,21 +132,6 @@ void initLabelMetrics() {
s_scale_use_vlw = false;
}

applyScaleStyle();
s_scale_label_h = tft.fontHeight();
s_scale_label_max_w = 0;
char label[12];
for (size_t i = 0; i < radar::kRangePresetCount; ++i) {
for (bool miles : {false, true}) {
radar::formatRing3Label(label, sizeof(label), radar::kRangePresets[i].ring3_km,
miles);
const int w = tft.textWidth(label);
if (w > s_scale_label_max_w) {
s_scale_label_max_w = w;
}
}
}

s_label_metrics_ready = true;
}

Expand Down Expand Up @@ -382,7 +364,6 @@ void applyTagStyle() {
}

int measureTagBlockWidth(const services::adsb::Aircraft& plane) {
applyTagStyle();
int max_w = 0;
if (plane.callsign[0] != '\0') {
const int w = s_draw->textWidth(plane.callsign);
Expand All @@ -406,9 +387,6 @@ int measureTagBlockWidth(const services::adsb::Aircraft& plane) {
}

void drawAircraftTag(int x, int y, const services::adsb::Aircraft& plane) {
initTagLabelMetrics();
applyTagStyle();

const int line_h = s_draw->fontHeight();
const int block_w = measureTagBlockWidth(plane);
const int block_h = line_h * 3;
Expand Down Expand Up @@ -488,7 +466,13 @@ void sortBeyondDotsFarFirst(BeyondDotDrawItem* items, size_t count) {
void drawAircraft() {
initLabelMetrics();

const size_t n = services::adsb::aircraftCount();
// Stale data (no successful fetch recently) shows an empty scope rather
// than aircraft frozen at their last known positions.
constexpr unsigned long kAircraftStaleAfterMs = 15000;
const size_t n =
(millis() - services::adsb::lastSuccessMs() > kAircraftStaleAfterMs)
? 0
: services::adsb::aircraftCount();
const services::adsb::Aircraft* planes = services::adsb::aircraftList();

AircraftDrawItem items[services::adsb::kMaxAircraft];
Expand Down Expand Up @@ -531,6 +515,8 @@ void drawAircraft() {
drawBeyondRingDot(dots[d].x, dots[d].y);
}

initTagLabelMetrics();
applyTagStyle(); // once per frame; tag text metrics stay valid below
sortDrawItemsFarFirst(items, draw_count);
for (size_t d = 0; d < draw_count; ++d) {
const size_t i = items[d].index;
Expand Down Expand Up @@ -651,7 +637,6 @@ void drawStaticGrid(Gfx& gfx) {
gfx.fillScreen(radar::kColorBackground);
drawRings(cx, cy, grid_r);
drawCrosshairs(cx, cy, grid_r, radar::kColorGrid);
initPalette();
runway::drawLargeAirportRunways(gfx);
drawCenterDot(cx, cy);
drawCardinalLabels();
Expand Down
2 changes: 0 additions & 2 deletions src/ui/radar_range.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ void rangeNext() {

const RangePreset& rangeCurrent() { return kRangePresets[s_range_index]; }

uint8_t rangeIndex() { return s_range_index; }

float fetchRadiusKm() {
const float outer_km = rangeCurrent().outer_km;
const float screen_r_px =
Expand Down
21 changes: 11 additions & 10 deletions src/ui/runway_overlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,20 +145,21 @@ bool segmentIntersectsDisc(int x0, int y0, int x1, int y1) {
const int dy = y1 - y0;
const int fx = x0 - cx;
const int fy = y0 - cy;
const int a = dx * dx + dy * dy;
if (a == 0) {
const float a = static_cast<float>(dx) * dx + static_cast<float>(dy) * dy;
if (a == 0.0f) {
return false;
}
const int b = 2 * (fx * dx + fy * dy);
const int c = fx * fx + fy * fy - r_sq;
int disc = b * b - 4 * a * c;
if (disc < 0) {
const float b = 2.0f * (static_cast<float>(fx) * dx + static_cast<float>(fy) * dy);
const float c = static_cast<float>(fx) * fx + static_cast<float>(fy) * fy -
static_cast<float>(r_sq);
const float disc = b * b - 4.0f * a * c;
if (disc < 0.0f) {
return false;
}
disc = static_cast<int>(sqrtf(static_cast<float>(disc)));
const float inv2a = 1.0f / (2.0f * static_cast<float>(a));
const float t0 = (-static_cast<float>(b) - disc) * inv2a;
const float t1 = (-static_cast<float>(b) + disc) * inv2a;
const float sq = sqrtf(disc);
const float inv2a = 1.0f / (2.0f * a);
const float t0 = (-b - sq) * inv2a;
const float t1 = (-b + sq) * inv2a;
return (t0 >= 0.0f && t0 <= 1.0f) || (t1 >= 0.0f && t1 <= 1.0f);
}

Expand Down