std.astro.groundtrack — Bodenspur

Diese Unit schließt ein einzelnes Glied: die Drehung vom Inertialsystem auf die drehende Erde. Vorne liegt std.astro.state mit dem Ortsvektor im ECI, hinten std.geodesy.frames mit EcefToGeod. Dazwischen fehlte die Drehung um den Greenwich-Stundenwinkel — und die ist der ganze Unterschied zwischen beiden Rahmen (#1995).

std.astro (Übersicht) · std.astro.orbit · std.astro.state · std.geodesy.frames · Bahntypen


1. Warum eine eigene Unit

Der Grund ist die Zeitachse. Alles in std.astro.orbit rechnet zeitlos: eine Bahn hat eine Umlaufzeit, aber keinen Zeitpunkt. Sobald ein Datum ins Spiel kommt — und ohne Datum gibt es keinen Stundenwinkel —, ist das eine andere Art von Rechnung.

Die Abhängigkeit zeigt außerdem bewusst nicht auf std.geodesy. Die Unit liefert den Unterpunkt geozentrisch, also auf der Kugel, und den ECEF-Vektor. Wer die geodätische Breite auf dem Ellipsoid braucht, verkettet selbst mit EcefToGeod. Der Unterschied ist nicht klein — bis zu 0.19 Grad in mittleren Breiten —, aber die Wahl gehört dem Aufrufer.

2. Die Funktionen

Funktion Rückgabe Bedeutung
AJ2000() f64 julianisches Datum der Epoche J2000.0 = 2 451 545.0
AJulianCenturies(jd) f64 julianische Jahrhunderte seit J2000.0
AGmst(jd) f64 Greenwich-Sternzeit als Winkel in Radiant
AEciToEcef(v, gmst) AVec3 Drehung ins erdfeste System
AEcefToEci(v, gmst) AVec3 die Gegenrichtung
ASubPointLatitude(v) f64 geozentrische Breite des Unterpunkts (aus dem ECI-Vektor)
ASubPointLongitude(v, gmst) f64 Länge des Unterpunkts
ASubPointAltitude(v, rBody) f64 Höhe über der Kugel

Die Breite braucht keinen Stundenwinkel: die Drehung geht um die z-Achse und lässt die Breite unberührt. Nur die Länge hängt an der Zeit.

3. Die Bodenspur eines Umlaufs

Ein Satellit auf einer 400-km-Kreisbahn, Startpunkt auf der x-Achse des ECI, Epoche JD 2 460 000.5:

Zeit GMST Länge des Unterpunkts
0.0 min 154.602° −154.602°
23.1 min 160.403° −70.403°
46.3 min 166.204° 13.796°
69.4 min 172.005° 97.995°
92.6 min 177.805° −177.805°

Die letzte Zeile ist der ganze Punkt: nach einem vollen Umlauf steht der Satellit wieder über demselben Inertialpunkt, aber die Länge ist von −154.602° auf −177.805° gewandert. 23.2 Grad Westdrift je Umlauf — die Erde hat sich in den 92.56 Minuten weitergedreht. Genau diese Drift muss eine Wiederholbahn so treffen, dass sie sich nach ganzen Tagen schließt.

Zwei Proben stehen daneben:

  • Ein Vektor über dem Nordpol liefert 90.0° Breite, unabhängig vom Stundenwinkel.
  • AEcefToEci(AEciToEcef(v, gmst), gmst) gibt denselben Vektor zurück — 6 778 137.0 m, auf den Meter.

4. Das Programm

unit main;
import std.astro.groundtrack;
import std.astro.orbit;
import std.astro.state;
import std.math;
import std.io;
import std.string;

fn f(v: f64, d: int64): pchar { return FloatToStr(v, d); }
fn G(r: f64): f64 { return r * 180.0 / Pi(); }

fn main(): int64 {
    // ISS-artige Bahn, 400 km, der Einfachheit halber in der Aequatorebene
    var r:   f64 := ARadiusEarth() + 400000.0;
    var T:   f64 := APeriod(AMuEarth(), r);
    var jd0: f64 := 2460000.5;

    PrintLn(StrConcat("Umlaufzeit: ", StrConcat(f(T / 60.0, 2), " min")));
    PrintLn("");
    PrintLn("Minute | GMST Grad | Laenge Grad");

    var i: int64 := 0;
    while i <= 4 {
        var dt:   f64 := (i as f64) * T / 4.0;
        var jd:   f64 := jd0 + dt / 86400.0;
        var gmst: f64 := AGmst(jd);
        // Position auf der Kreisbahn nach dt Sekunden
        var w:    f64 := SqrtF64(AMuEarth() / (r * r * r));
        var eci:  AVec3 := AVec(r * CosF64(w * dt), r * SinF64(w * dt), 0.0);
        Print(f(dt / 60.0, 1));
        Print(" | "); Print(f(G(gmst), 3));
        Print(" | "); PrintLn(f(G(ASubPointLongitude(eci, gmst)), 3));
        i := i + 1;
    }

    PrintLn("");
    PrintLn(StrConcat("J2000 als julianisches Datum: ", f(AJ2000(), 1)));
    PrintLn(StrConcat("Jahrhunderte seit J2000:      ", f(AJulianCenturies(jd0), 6)));
    var eci2: AVec3 := AVec(0.0, 0.0, r);
    PrintLn(StrConcat("Ueber dem Nordpol, Breite:    ", StrConcat(f(G(ASubPointLatitude(eci2)), 1), " Grad")));
    PrintLn(StrConcat("Hin und zurueck (ECI->ECEF->ECI) x: ", f(AEcefToEci(AEciToEcef(eci2, AGmst(jd0)), AGmst(jd0)).z, 1)));
    return 0;
}

Ausgabe:

Umlaufzeit: 92.56 min

Minute | GMST Grad | Laenge Grad
0.0 | 154.602 | -154.602
23.1 | 160.403 | -70.403
46.3 | 166.204 | 13.796
69.4 | 172.005 | 97.995
92.6 | 177.805 | -177.805

J2000 als julianisches Datum: 2451545.0
Jahrhunderte seit J2000:      0.231499
Ueber dem Nordpol, Breite:    90.0 Grad
Hin und zurueck (ECI->ECEF->ECI) x: 6778137.0

 
Die Zeit ist hier die Fehlerquelle, nicht die Geometrie. AGmst erwartet ein julianisches Datum, und ein Tag Abweichung dreht die Länge um knapp ein Grad daneben — der Sterntag ist vier Minuten kürzer als der Sonnentag. Wer eine Bodenspur über Wochen rechnet, muss die Epoche sauber führen.