ISS-Sichtbarkeitsampel für die ASTW

numerische_astronomie
nasa
esa
python
iss
Autor:in

Ansgar Schmidt

Veröffentlichungsdatum

11. April 2025

Wir planen die Installation einer Ampel, die uns auf der ASTW über bevorstehende Überflüge der Internationalen Raumstation (ISS) informieren soll. Diese Ampel wird in drei Farben leuchten, um den Sichtbarkeitsstatus der ISS anzuzeigen:

Um die Realisierung in dieser ersten Phase zu vereinfachen, werden wir die Farben der Ampel primär anhand der Höhe der ISS über dem Horizont bestimmen. Diese vereinfachte Methode kann zwar potenziell zu falschen Vorwarnungen für eine bevorstehende Sichtbarkeit führen, beispielsweise wenn die ISS zwar hoch am Himmel steht, aber die Lichtverhältnisse ungünstig sind (z.B. tagsüber), für die erste Version unseres Projekts soll dieser Ansatz jedoch ausreichend sein. In späteren Ausbaustufen könnten komplexere Berechnungen und Datenquellen hinzugezogen werden, um die Genauigkeit der Vorhersagen zu verbessern.

Um den Entwicklungsprozess effizient zu gestalten, werden wir den benötigten Code in zwei separate Komponenten aufteilen: einen “Server” und einen “Client”.

Der Server wird als einfacher Docker-Container implementiert. Dieser Container wird über eine Programmierschnittstelle (API) die Farbinformationen in Form von numerischen Werten bereitstellen: 0 für Rot, 1 für Gelb und 2 für Grün. Die Verwendung eines Docker-Containers ermöglicht eine einfache Bereitstellung und Ausführung des Servers in verschiedenen Umgebungen.

Der Client, dessen detaillierte Beschreibung später erfolgen wird, wird ein einfacher ESP32-Mikrocontroller sein. Dieser ESP32 wird die von der Server-API bereitgestellten Farbinformationen empfangen und direkt die Ampel ansteuern. Der Client übernimmt dabei keine komplexen Berechnungen zur Vorhersage der ISS-Sichtbarkeit.

Wir sind zuversichtlich, dass diese ISS-Sichtbarkeitsampel eine interessante und informative Ergänzung für die ASTW darstellen wird und den Besuchern ein einzigartiges Erlebnis bietet.

!pip install skyfield

Für die Berechnung in Python werden wir die Bibliothek Skyfield verwenden, um die Entwicklung zu vereinfachen und die komplexe mathematische Berechnung an Entwickler*innen auszulagern, die über eine größere Expertise in diesem Bereich verfügen als wir.

import requests
from   skyfield.api      import load, EarthSatellite
from   skyfield.toposlib import wgs84

Darüber hinaus werden wir erneut die requests-Bibliothek verwenden, um auf einfache Weise einen API-Aufruf durchzuführen.

URL = "https://celestrak.org/NORAD/elements/gp.php?GROUP=stations&FORMAT=tle"

Die eigentlichen TLE Daten bekommen wir von Celestrak.

lines = requests.get(URL).text.strip().split('\n')

for i, line in enumerate(lines):
    if "ISS" in line:
        tle_line1 = lines[i + 1]
        tle_line2 = lines[i + 2]
        break

Celestrak stellt uns über diesen Aufruf TLE-Daten aller Raumstationen zur Verfügung. Da wir jedoch nur die Daten der ISS benötigen, extrahieren wir diese spezifisch mit diesem Aufruf. Hier ist lediglich die Kernfunktionalität dargestellt. Selbstverständlich müssen um diesen Aufruf herum noch Prüfungen implementiert werden, um sicherzustellen, dass der API-Aufruf erfolgreich war und die empfangenen Daten tatsächlich die ISS enthalten.

Ebenso ist es notwendig, den gesamten Aufruf mit einem Cache zu versehen, damit die TLE-Daten nicht bei jedem API-Aufruf vom Server neu geladen werden, sondern beispielsweise nur alle 24 Stunden. Wir haben diesen Codeabschnitt hier weggelassen, um die Darstellung übersichtlicher zu gestalten.

print(f"{tle_line1}\n{tle_line2}")
1 25544U 98067A   25099.02883663  .00012701  00000+0  23524-3 0  9990
2 25544  51.6387 289.5561 0005135  20.7798 117.4947 15.49367294504434

Wunderbar, hier haben wir die aktuellen TLE Daten der ISS.

satellite = EarthSatellite(tle_line1, tle_line2, 'ISS')

Mit diesem Aufruf wird in Skyfield ein Erdtrabant-Objekt angelegt, mit dem alle weiteren Berechnungen durchgeführt werden können.

In der Regel beobachten unsere Besucher die Internationale Raumstation (ISS), während sie sich auf dem Vorplatz des Teleskops aufhalten. Aus diesem Grund werden wir nun diese spezifischen Daten verwenden. Maps

observer_lat       = 52.4867411
observer_lon       = 13.4752692
observer_elevation = 23
observer           = wgs84.latlon(observer_lat, observer_lon, observer_elevation)

Ähnlich wie satellite stellt nun observer ein Objekt für die Berechnung dar. Dieses Objekt repräsentiert den spezifischen Punkt auf der Erde, von dem aus die Beobachtung durchgeführt wird. Es ist ein sogenanntes Topos Objekt.

difference        = satellite - observer
topocentric       = difference.at(load.timescale().now())
alt, az, distance = topocentric.altaz()

Diese Zeilen berechnen die Position eines Satelliten relativ zu einem Beobachter auf der Erde und bestimmen dessen Höhe über dem Horizont (alt), Richtung (az) und Entfernung (distance).

Die Subtraktion satellite - observer erzeugt ein relatives Positionsobjekt, das die Differenz zwischen Satellit und Beobachter im Raum repräsentiert. Damit kann später die Position des Satelliten vom Standort des Beobachters aus berechnet werden (topozentrische Koordinaten).

load.timescale().now() erzeugt ein Time-Objekt mit der aktuellen Systemzeit (UTC) mit die Skyfield-Zeitskala (für präzise astronomische Berechnungen). .now() gibt dabei den aktuellen Zeitpunkt zurück.

difference.at(t) berechnet die relative Position des Satelliten zum Beobachter zum Zeitpunkt t. Das Ergebnis (topocentric) ist ein Geocentric- oder Topos-Objekt, das die Position des Satelliten in einem Koordinatensystem beschreibt, das vom Beobachter ausgerichtet ist.

Die Methode .at() ist notwendig, um die Position für einen konkreten Zeitpunkt zu berechnen (Ephemeridenrechnung).
Ohne diesen Schritt wüssten wir nur die Bahn, nicht die aktuelle Position.

topocentric.altaz() berechnet die horizontbezogenen Koordinaten (Azimut/Höhe) des Satelliten.
- alt (Höhe über dem Horizont in Grad):
- = Horizont, 90° = Zenit (direkt über dem Beobachter).
- Negativ = Unter dem Horizont.
- az (Azimut in Grad, Himmelsrichtung):
- = Norden, 90° = Osten, 180° = Süden, 270° = Westen.
- distance (Entfernung in Kilometern).

print(f"Höhe über Horizont: {alt.degrees:.2f}° \nEntfernung: {distance.km:.2f} Kilometer")
Höhe über Horizont: -34.34° 
Entfernung: 7914.46 Kilometer

Somit verfügen wir über alle notwendigen Informationen. Diese müssen nun in einem Container zusammengefasst, der TLE-Cache implementiert und mithilfe eines einfachen Codes eine API bereitgestellt werden. Die detaillierte Struktur des Clients wird im nächsten Artikel erläutert.

Das Repository fuer den Docker Container befindet sich hier und der Docker Container kann mit

docker run -it --rm -p 8578:8578 registry.gitlab.com/astw/tools/iss-locator

gestartet werden

Zurück nach oben