v2.6.5: Add arrowhead to aircraft heading line on radar

drawAircraftMarker() previously drew a plain symmetric line for an
aircraft's heading, making it impossible to tell at a glance which
end pointed "forward". The line now ends in a small two-stroke
arrowhead (chevron), so the direction of travel is unambiguous.

Also documents that the index.html version-badge check (release
workflow step 4) is mandatory and not optional, since it was
accidentally skipped on a recent patch release.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Eiswolf-BG
2026-08-06 16:39:02 +02:00
parent 58bdedae31
commit 406326f3da
3 changed files with 41 additions and 5 deletions

View File

@@ -146,8 +146,18 @@ falls der Nutzer danach fragt: weitere Menüs mit Info-Buttons versehen,
ggf. weitere Sprachen, ggf. Export/Teilen der Logbuch-Daten.
## Standard-Workflow: Push & Release
Bei JEDEM Release-Push (egal ob großes Feature oder kleiner Bugfix) automatisch
folgende Schritte in dieser Reihenfolge:
WICHTIG - wann dieser Workflow startet: Der komplette Release-Workflow
(README-Update, Commit, Tag, Push) darf NUR gestartet werden, wenn Alex
EXPLIZIT danach fragt (z.B. "lass pushen", "können wir releasen", "mach den
Release-Workflow"). Ein einfaches "ja" auf eine Rückfrage (z.B. zu einer
CLAUDE.md-Änderung oder einem anderen Detail) ist KEINE Aufforderung, den
Release-Workflow zu starten. Bei kleineren Fixes/Änderungen bitte NUR bauen
und flashen (siehe Abschnitt "Nach jedem erfolgreichen Build automatisch
flashen" unten), aber NICHT committen/taggen/pushen, bis ausdrücklich danach
gefragt wird.
Sobald der Workflow explizit angefordert wurde, automatisch folgende Schritte
in dieser Reihenfolge:
1. Prüfen, ob seit dem letzten Commit neue/geänderte Features hinzugekommen
sind, die für Endnutzer sichtbar sind (neue Menüpunkte, geändertes
@@ -160,7 +170,12 @@ folgende Schritte in dieser Reihenfolge:
3. Falls es sich um einen Versionssprung handelt: Git-Tag mit
Versionsnummer + Beschreibung der Änderungen erstellen.
4. Prüfen, ob `index.html` (Web-Flasher) noch die alte Versionsnummer zeigt -
falls ja, aktualisieren.
falls ja, aktualisieren. **NICHT OPTIONAL, darf bei KEINEM Release-Push
übersprungen werden** - auch nicht bei kleinen Patch-Versionen. Immer als
fester Doppel-Schritt zusammen mit Schritt 1 (README) behandeln: wann
immer die README (oder auch nur die Versionsnummer) auf eine neue Version
aktualisiert wird, IMMER im selben Zug auch `index.html` prüfen und
synchron mitziehen.
5. Prüfen, ob `bootloader.bin`, `firmware.bin`, `partitions.bin` im
Hauptverzeichnis dem aktuellen Build in `.pio/build/esp32dev/`
entsprechen - falls nicht, von dort kopieren.

View File

@@ -26,7 +26,7 @@ You can flash the firmware directly from your browser to your CYD display withou
---
## Features
- **Live radar screen** – circular radar view, sized to the full screen width, with a rotating green sweep line
- **Live radar screen** – circular radar view, sized to the full screen width, with a rotating green sweep line; each aircraft marker's heading line ends in a small arrowhead, so its direction of travel is unambiguous at a glance
- **Real ADS-B data** via the free [adsb.fi](https://adsb.fi) API, refreshed every 8 seconds
- **Color-coded aircraft** by altitude (green `<10k ft`, yellow `10-30k ft`, red `>30k ft`) with an on-screen legend
- **Tap an aircraft** to open a detail panel: callsign, airline, aircraft model (via [hexdb.io](https://hexdb.io)), altitude/speed/distance/heading in both metric and aviation units, estimated seat count

View File

@@ -90,13 +90,34 @@ namespace {
return TFT_RED;
}
// kurzer Kursstrich in Flugrichtung (headingDeg) MIT Pfeilspitze am Ende -
// eine reine Linie ohne Spitze war nicht eindeutig lesbar (nicht erkennbar,
// welches Ende "vorne" ist). Die Spitze besteht aus zwei kurzen Strichen,
// die knapp vor der Linienspitze schraeg nach aussen abzweigen (klassisches
// Chevron-/Pfeilkopf-Symbol, wie bei ATC-Radardarstellungen ueblich).
void drawAircraftMarker(TFT_eSPI& gfx, int16_t x, int16_t y, float headingDeg, uint16_t color) {
gfx.fillCircle(x, y, 5, color);
double rad = headingDeg * PI / 180.0;
int16_t dx = (int16_t)(sin(rad) * 10);
int16_t dy = (int16_t)(-cos(rad) * 10);
gfx.drawLine(x, y, x + dx, y + dy, color);
int16_t tipX = x + dx;
int16_t tipY = y + dy;
gfx.drawLine(x, y, tipX, tipY, color);
// Pfeilspitze: zwei kurze Striche von der Spitze aus, je 150 Grad
// zur Kurslinie zurueckgeklappt (also leicht "nach hinten" zeigend,
// wie bei einem Pfeilkopf "^" ueblich).
constexpr double WING_ANGLE_RAD = 150.0 * PI / 180.0;
constexpr int16_t WING_LEN = 4;
double wing1 = rad + WING_ANGLE_RAD;
double wing2 = rad - WING_ANGLE_RAD;
int16_t w1x = tipX + (int16_t)(sin(wing1) * WING_LEN);
int16_t w1y = tipY + (int16_t)(-cos(wing1) * WING_LEN);
int16_t w2x = tipX + (int16_t)(sin(wing2) * WING_LEN);
int16_t w2y = tipY + (int16_t)(-cos(wing2) * WING_LEN);
gfx.drawLine(tipX, tipY, w1x, w1y, color);
gfx.drawLine(tipX, tipY, w2x, w2y, color);
}
uint16_t dimColorForAltitude(int32_t altFt) {