GRT-Based Landing Guidance (#981)

Overview

Replaces the reactive target-retrograde landing controller with a reference trajectory + corrections approach based on the Generalized Reference Targeting (GRT) framework (AAS 25-099). Target: 10m landing accuracy for targeted landings on any body.

Phase Flow

Targeted landings: plane_change → coast_to_deorbit → deorbit → braking → glide → powered_descent → touchdown

  • For near-equatorial targets (target latitude < 10°), plane_change is skipped entirely (#1003). The orbital plane change oscillates and wastes fuel at low inclinations, so the glide phase handles crosstrack correction instead.
  • The glide phase uses ZEM/ZEV guidance to steer toward the target pad while descending.
  • The powered_descent phase is the final precision landing phase, also using ZEM/ZEV guidance, entered when horizontal distance and velocity are small enough.
  • Both glide and powered_descent can transition directly to touchdown when AGL and descent rate are below terminal thresholds.
  • Targeted landings are always routed through glide/powered_descent. If a targeted landing is ever found in the old vertical_descent, hover_steer, or terminal phases, it is redirected to glide (#1012).

Untargeted landings: deorbit → braking → vertical_descent → terminal → touchdown

Untargeted landings retain the existing controller with no regression.

Algorithm

1. Plane Change Phase

Goal: Adjust orbital plane so ground track passes through target latitude.

Skip condition: For near-equatorial targets (target latitude < 10°), plane change is skipped entirely and the maneuver proceeds directly to coast_to_deorbit (#1003). At low inclinations, the out-of-plane steering oscillates between inclination and RAAN corrections, wasting fuel. The glide phase handles crosstrack correction instead.

Attitude: Orbit-normal steering (Q-law)

2. Coast to Deorbit Phase

Goal: Wait until the ship’s ground track passes near the target longitude, then initiate the deorbit burn.

Algorithm:

  1. Compute body-fixed longitude of the ship
  2. Compare to target longitude, accounting for body rotation
  3. Transition to deorbit when near the deorbit window and crosstrack error is within budget

3. Deorbit Phase

Goal: Fire a retrograde burn to lower the periapsis and begin descent toward the target.

Transitions to: braking once the burn is complete (periapsis lowered sufficiently or altitude begins decreasing)

4. Braking Phase

Goal: Kill orbital horizontal velocity before entering precision guidance.

Transitions:

  • Targeted landings: When horizontal speed < 200 m/s, transitions to glide
  • Untargeted landings: When horizontal speed is sufficiently reduced, transitions to vertical_descent

5. Glide Phase (ZEM/ZEV Guidance)

Goal: Steer toward the target pad using ZEM/ZEV closed-form guidance while descending.

Guidance law: ZEM/ZEV (Zero-Effort Miss / Zero-Effort Velocity)

Per-tick guidance cycle:

  1. Compute time-to-go: t_go based on current state and target
  2. Compute ZEM/ZEV correction (algebraic, no iteration):
    ZEM = δr + δv × t_go + 0.5 × g × t_go²    (zero-effort miss)
    ZEV = δv + g × t_go                          (zero-effort velocity)
    a_cmd = 6 × ZEM / t_go² - 2 × ZEV / t_go    (commanded acceleration)
    
  3. Add gravity compensation: a_total = a_cmd - g(r)
  4. Compute thrust direction and level:
    thrust_dir = normalize(a_total)
    thrust_level = |a_total| / thrust_accel_max
    
  5. Apply high-AGL descent bias (#1051): When AGL > 10 km, add a radially-inward acceleration bias to break horizontal oscillation at orbital altitude. Without this, the ZEM/ZEV closing velocity is near-zero in a near-circular orbit (velocity is tangential), producing huge t_go and negligible position corrections. The ship dithers horizontally instead of descending.
    alpha = clamp((AGL - 10 km) / (50 km - 10 km), 0, 1)        # altitude ramp
    v_desired = 0.1 × sqrt(2 × g_local × AGL)                    # minimum descent rate
    deficit = clamp((v_desired - v_radial_down) / v_desired, 0, 1) # velocity ramp
    a_bias = alpha × deficit × g_local                            # radially inward
    a_cmd += a_bias × (-r̂)
    

    The bias is self-limiting: once the ship establishes sufficient descent velocity, deficit drops to zero and the bias turns off, leaving pure ZEM/ZEV for terminal approach.

  6. Apply low-AGL descent rate limiter (#1051): When AGL < 2 km and descent rate exceeds the safe stopping-distance profile, add a radially-outward (upward) bias to ensure the ship can arrest its descent before surface contact. Without this, ZEM/ZEV at low altitude with significant lateral offset commands mostly horizontal thrust (toward the pad), leaving insufficient vertical braking — the ship crashes short of the pad.
    net_decel = thrust_accel - g_local                              # pure-radial budget
    safe_rate = sqrt(2 × net_decel × 0.5 × AGL)                   # can stop in 50% of AGL
    excess = clamp((v_radial_down - safe_rate) / safe_rate, 0, 1)  # overshoot fraction
    a_bias = excess × thrust_accel                                  # radially outward
    a_cmd += a_bias × r̂
    

    The limiter is progressive: small corrections at moderate overshoot, full vertical override when descent rate far exceeds the safe profile. When the engine is thrust- saturated, the clamping naturally shifts the thrust direction upward, sacrificing lateral correction to prioritize survival.

  7. Vertical safety override: Last-resort hard cutover when stopping distance exceeds 70% of remaining AGL. Commands pure radial thrust at 100%.
  8. Terminal transition (#1051): When AGL < 2 km and descent rate < 30 m/s, transition from ZEM/ZEV descent to the terminal phase. ZEM/ZEV is effective for the high-altitude approach but the main engine (8.5× gravity on Callisto) is too powerful for fine hover control, causing oscillation. The terminal phase uses:
    • Main engine at PID-controlled hover thrust (vertical rate management)
    • Engine tilt toward pad (max 0.2 rad / 11.5°) for lateral correction
    • RCS thrusters for fine lateral adjustments
    • Descent rate profile: sqrt(2 × 0.1 × AGL), min 1.0 m/s Transitions to touchdown at AGL < 10m.
  9. Compute thrust direction and level:
    thrust_dir = normalize(a_total)
    thrust_level = |a_total| / thrust_accel_max
    
  10. Issue steering command: ATTITUDE_DIRECTION with computed direction and throttle

Transitions:

  • When horizontal distance and velocity are small enough and at minimum hover altitude, transitions to powered_descent
  • If AGL and descent rate are below terminal thresholds, transitions directly to touchdown

6. Powered Descent Phase (ZEM/ZEV Guidance)

Goal: Final precision landing using ZEM/ZEV guidance for the last approach to the pad.

Uses the same ZEM/ZEV guidance law as the glide phase, but entered when the ship is close to the target with low relative velocity.

Terminal conditions:

  • AGL < 2m AND descent_rate < 5 m/s → transitions to touchdown
  • OR physics reports landed_body_name set

7. Touchdown Phase

Goal: Final contact with the surface. Engines off, landing complete.

Safety Redirects

Targeted landings must always use the glidepowered_descent path. If a targeted landing is ever found in the old vertical_descent, hover_steer, or terminal phases (e.g., due to a regression from altitude-based phase guards), it is redirected back to glide (#1012).

Data Flow

maneuver Redis hash:
  phase: one of "plane_change", "coast_to_deorbit", "deorbit",
         "braking", "glide", "powered_descent", "touchdown"
         (untargeted also uses: "vertical_descent", "hover_steer", "terminal")
  target_body: name of the body being landed on
  target_nx, target_ny, target_nz: target pad surface normal (ICRF)
  zemzev_last_dir: filtered guidance direction (reset on phase change)
  status_text: human-readable phase description
  pid_integral, pid_last_error: PID state for altitude control

Constants

Constant Value Description
TERMINAL_AGL 10.0 m Touchdown detection altitude
TERMINAL_RATE 5.0 m/s Touchdown detection descent rate
APPROACH_ARRIVAL_DIST 5000 m Glide→powered_descent horizontal distance threshold
APPROACH_ARRIVAL_VEL 100 m/s Glide→powered_descent velocity threshold
APPROACH_MIN_HOVER_ALT 5000 m Minimum hover altitude for glide→powered_descent transition
HIGH_AGL_BIAS_FLOOR 10,000 m AGL below which descent bias is zero
HIGH_AGL_BIAS_CEILING 50,000 m AGL above which descent bias is at full strength
LOW_AGL_LIMITER_CEILING 2,000 m AGL below which descent rate limiter is active
LOW_AGL_LIMITER_SAFETY_FACTOR 0.5 Must be able to stop in this fraction of remaining AGL
TARGETED_TERMINAL_ALT 2,000 m AGL below which targeted landings transition from ZEM/ZEV to terminal
TARGETED_TERMINAL_RATE 30 m/s Max descent rate for descent→terminal transition
PLANE_CHANGE_SKIP_THRESHOLD 10° Target latitude below which plane change is skipped

Modules

File Purpose
maneuver_landing.py Phase dispatch, plane change, coast, deorbit, braking, terminal, touchdown
zemzev_guidance.py ZEM/ZEV guidance: glide and powered_descent phase handlers

Test Requirements

Precision landing tests with 10m tolerance:

  • Io equatorial (lat=0, lon=0)
  • Luna equatorial (lat=0, lon=0)
  • Io mid-latitude (lat=30, lon=45)

All tests bypass coast phase (place ship above target) to isolate descent controller accuracy.

Dependencies

  • #981 (this feature)
  • Existing plane_change phase (retained)
  • Physics service (N-body integration, surface contact detection)

References

  • Geller, Woffinden, York. “Generalized Reference Targeting for Spaceflight.” AAS 25-099.
  • D’Souza. “An Optimal Guidance Law for Planetary Landing.” AIAA-97-0640.

Back to top

Galaxy — Kubernetes-based multiplayer space game

This site uses Just the Docs, a documentation theme for Jekyll.