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.AGmsterwartet 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.
