diff --git a/CLAUDE.md b/CLAUDE.md index aaaf159..977bdf8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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. diff --git a/README.md b/README.md index 16b4856..1aa703c 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/radar_screen.cpp b/src/radar_screen.cpp index 4d992e2..20ce2b5 100644 --- a/src/radar_screen.cpp +++ b/src/radar_screen.cpp @@ -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) {