Inhaltsverzeichnis

std.astro.guidance — Annäherung, Abweichung, Proportional Navigation

import std.astro.guidance;

Alles, was aus Relativvektoren folgt: Abstand, Annäherungsrate, dichteste Annäherung, Restflugzeit, Sichtlinienrate und die Sollbeschleunigung der Proportional Navigation.

Alle Funktionen nehmen rRel und vRel — Ort und Geschwindigkeit des Ziels relativ zum eigenen Fahrzeug, im selben Rahmen. Wer absolute Zustände hat, bildet vorher die Differenz.

std.astro (Übersicht) · std.astro.attitude · std.astro.state


1. Abstand und Annäherung

Funktion Rückgabe Bedeutung
ARange(rRel) f64 [m] Abstand
AClosingSpeed(rRel, vRel) f64 [m/s] Annäherungsrate; positiv beim Näherkommen
ATimeToCPA(rRel, vRel) f64 [s] Zeit bis zur dichtesten Annäherung; negativ heißt: der Punkt liegt hinter uns
ADistanceAtCPA(rRel, vRel) f64 [m] Abstand in diesem Punkt
ARelPositionAt(rRel, vRel, t) AVec3 geradlinig fortgeschriebene Relativposition
ATimeToGo(rRel, vRel) f64 [s] Restflugzeit; NaN, wenn sich das Ziel entfernt
AGuidanceThreshold() f64 1e−12
 
ATimeToGo meldet lieber NaN als eine große Zahl. Entfernt sich das Ziel, gibt es keine Restflugzeit — ein großer positiver Wert wäre dort besonders gefährlich, weil er aussieht wie „noch viel Zeit„.

2. Abweichung von der Bahn

Funktion Rückgabe Bedeutung
ACrossTrack(rRel, vRel) f64 [m] Querabweichung — senkrecht auf die Geschwindigkeitsrichtung
AAlongTrack(rRel, vRel) f64 [m] Abstand entlang der Bahngeraden, positiv wenn das Ziel voraus liegt
 
Gemessen wird senkrecht auf die Bewegungsrichtung, nicht auf die Verbindungslinie. Der Unterschied ist keine Kleinigkeit: bei 50 km Abstand und 50 Grad zwischen beiden liegen 12 km dazwischen. Der Fehler fällt nur auf, wenn ein Test einen schiefen Fall rechnet — ein rechtwinkliger gibt beidesmal dasselbe.

3. Sichtlinie und Proportional Navigation

Funktion Rückgabe Bedeutung
ALosRate(rRel, vRel) AVec3 [rad/s] Drehvektor der Sichtlinie: (r × v)/|r|² — Betrag = Rate, Richtung = Drehachse
ALosRateMagnitude(rRel, vRel) f64 [rad/s] nur der Betrag
ALosUnit(rRel) AVec3 Einheitsvektor der Sichtlinie
AProNavAccel(rRel, vRel, n) AVec3 [m/s²] Sollbeschleunigung N·V_c·(ω × r̂)
AOnCollisionCourse(rRel, vRel, rateSchranke) bool Sichtlinienrate unter der Schranke und Ziel kommt näher

Der Navigationsbeiwert n liegt üblich bei 3 bis 5.

 
Die Kernaussage der Proportional Navigation steht in einer Zahl: bei konstanter Sichtlinienrichtung ist ω null und damit die Sollbeschleunigung null — das ist Kollisionskurs. Die Beschleunigung steht senkrecht auf der Sichtlinie: sie stellt die Sichtlinie still, sie bremst nicht. Wer sie entlang der Sichtlinie ansetzt, fliegt eine Verfolgungskurve und keine Proportional Navigation.

AOnCollisionCourse prüft deshalb zwei Bedingungen. Eine ruhende Sichtlinie bei wachsendem Abstand ist gerade kein Kollisionskurs, sondern ein sich entfernendes Ziel auf derselben Geraden.

4. Beispiel

import std.astro.state;
import std.astro.guidance;
import std.io;

fn zeig(n: pchar, v: f64, d: int64): void { Print(n); PrintLn(FloatToStr(v, d)); }
fn BI(b: bool): int64 { if (b) { return 1; } return 0; }

fn main(): int64 {
    // Ziel 1000 m voraus, 50 m seitlich versetzt, kommt mit 10 m/s entgegen
    var r: AVec3 := AVec(1000.0, 50.0, 0.0);
    var v: AVec3 := AVec(0.0 - 10.0, 0.0, 0.0);

    zeig("Abstand m          : ", ARange(r), 1);
    zeig("Annaeherungsrate   : ", AClosingSpeed(r, v), 2);
    zeig("Zeit bis CPA s     : ", ATimeToCPA(r, v), 1);
    zeig("Abstand bei CPA m  : ", ADistanceAtCPA(r, v), 1);
    zeig("Restflugzeit s     : ", ATimeToGo(r, v), 1);
    zeig("Querabweichung m   : ", ACrossTrack(r, v), 1);
    zeig("Laengsabweichung m : ", AAlongTrack(r, v), 1);
    zeig("Sichtlinienrate    : ", ALosRateMagnitude(r, v), 6);

    var p: AVec3 := ARelPositionAt(r, v, 50.0);
    Print("Ort nach 50 s      : ("); Print(FloatToStr(p.x, 1));
    Print(", "); Print(FloatToStr(p.y, 1)); PrintLn(")");

    var a: AVec3 := AProNavAccel(r, v, 4.0);
    zeig("ProNav |a| m/s2    : ", AMagnitude(a), 4);
    Print("Kollisionskurs?    : "); PrintLn(IntToStr(BI(AOnCollisionCourse(r, v, 0.0001))));

    // Echter Kollisionskurs: genau aufeinander zu
    var rk: AVec3 := AVec(1000.0, 0.0, 0.0);
    var vk: AVec3 := AVec(0.0 - 10.0, 0.0, 0.0);
    zeig("gerade: Sichtrate  : ", ALosRateMagnitude(rk, vk), 6);
    zeig("gerade: ProNav |a| : ", AMagnitude(AProNavAccel(rk, vk, 4.0)), 6);
    Print("gerade: Kollision? : "); PrintLn(IntToStr(BI(AOnCollisionCourse(rk, vk, 0.0001))));

    // Ziel entfernt sich: keine Restflugzeit, kein Kollisionskurs
    var vw: AVec3 := AVec(10.0, 0.0, 0.0);
    Print("entfernt: t_go NaN : "); PrintLn(IntToStr(BI(AIsError(ATimeToGo(rk, vw)))));
    Print("entfernt: Kollis.? : "); PrintLn(IntToStr(BI(AOnCollisionCourse(rk, vw, 0.0001))));
    return 0;
}

Abstand m          : 1001.2
Annaeherungsrate   : 9.99
Zeit bis CPA s     : 100.0
Abstand bei CPA m  : 50.0
Restflugzeit s     : 100.3
Querabweichung m   : 50.0
Laengsabweichung m : -1000.0
Sichtlinienrate    : 0.000499
Ort nach 50 s      : (500.0, 50.0)
ProNav |a| m/s2    : 0.0199
Kollisionskurs?    : 0
gerade: Sichtrate  : 0.000000
gerade: ProNav |a| : 0.000000
gerade: Kollision? : 1
entfernt: t_go NaN : 1
entfernt: Kollis.? : 0

Der mittlere Block ist die eigentliche Aussage: auf genauem Kollisionskurs sind Sichtlinienrate und Sollbeschleunigung exakt null. Die Regelung tut nichts — weil nichts zu tun ist. Im schiefen Fall darüber ergibt dieselbe Rechnung 0.0199 m/s², und die Querabweichung von 50 m bleibt bis zur dichtesten Annäherung erhalten.

Der letzte Block zeigt die Gegenprobe: dasselbe Ziel, nur wegfliegend — die Restflugzeit ist NaN, und AOnCollisionCourse meldet trotz ruhender Sichtlinie korrekt „nein“.


Letzte Aktualisierung: 2026-09-01 — Seite neu angelegt aus std/astro/guidance.lyx (Commit 32353cc, #1900, 83 Prüfungen); Beispiel mit lyxc 1.1.16A gebaut und ausgeführt.