Surface Ascent to Orbit (#920)
Autonomous ascent from a landed state to a circular orbit around the current body.
Action
| Field | Value |
|---|---|
type |
ascend |
target_altitude |
Optional. Target circular orbit altitude in meters above mean radius. Defaults to SAFE_ORBIT_ALTITUDES[body_name] (e.g., 50 km for Luna, 200 km for Callisto). |
Precondition: Ship must be landed (landed_body_name is set).
Phase Flow
launch → gravity_turn → coast_to_apoapsis → circularize → complete
Phases
Phase: launch
Goal: Lift off the surface.
- Attitude:
ATTITUDE_LOCAL_VERTICAL(point away from body center) - Thrust: 100%
- The physics engine clears
landed_body_namewhen thrust exceeds weight - Transition: When
landed_body_nameis cleared AND AGL > 100m, advance togravity_turn - Status:
"Ascent — launch"
Phase: gravity_turn
Goal: Pitch from vertical toward horizontal to build orbital velocity while gaining altitude.
Algorithm:
- Compute radial direction (local vertical):
radial_hat = normalize(ship_pos - body_pos) - Compute horizontal velocity direction:
- If horizontal speed > 10 m/s: use actual horizontal velocity direction
- Otherwise: use body rotation “east” direction:
east = normalize(cross(spin_axis, radial_hat)) - For non-rotating bodies: use arbitrary horizontal direction from
cross((0,0,1), radial_hat)orcross((0,1,0), radial_hat)
- Compute pitch parameter:
t = clamp((AGL - turn_start_alt) / (target_alt × 0.3), 0, 1)- At
t=0: vertical (radial). Att=1: horizontal (prograde).
- At
- Blend direction:
direction = normalize((1 - t) × radial_hat + t × horiz_hat) - Command
ATTITUDE_DIRECTIONwith blended direction, thrust = 100%
Transition: When apoapsis altitude ≥ target altitude, advance to coast_to_apoapsis
Status: "Ascent — gravity turn, apo {apo_km}km / {target_km}km"
Phase: coast_to_apoapsis
Goal: Coast ballistically to apoapsis where the circularization burn is most efficient.
- Thrust: 0%
- Attitude:
ATTITUDE_PROGRADE(pre-align for circularization) - Apoapsis maintenance: If apoapsis drops below target (e.g., atmospheric drag), briefly re-engage thrust prograde until restored
- Transition: When true anomaly is within 15° of apoapsis, advance to
circularize - Status:
"Ascent — coast to apoapsis, {angle}° to apo"
Phase: circularize
Goal: Prograde burn at apoapsis to raise periapsis and achieve circular orbit.
Delegates to the existing maneuver_circularize_tick handler with target_sma set to body_radius + target_altitude. Uses the same convergence criteria (e < 0.03, SMA error < 2%, periapsis above surface).
On completion, calls _complete_maneuver.
Status: Reuses circularize status text.
Maneuver Hash Fields
| Field | Type | Description |
|---|---|---|
type |
string | "ascend" |
target_body |
string | Body being ascended from |
target_altitude |
string (meters) | Target circular orbit altitude above mean radius |
target_sma |
string (meters) | Target SMA = body_radius + target_altitude (set on first tick) |
phase |
string | "launch", "gravity_turn", "coast_to_apoapsis", "circularize" |
status_text |
string | Human-readable phase description |
Constants
| Constant | Value | Description |
|---|---|---|
ASCENT_VERTICAL_CLIMB_ALT |
100 m | Minimum AGL before starting gravity turn |
ASCENT_TURN_SCALE |
0.3 | Fraction of target altitude over which pitch goes from vertical to horizontal |
ASCENT_COAST_APOAPSIS_MARGIN |
0.95 | Start coast when apoapsis ≥ this × target |
ASCENT_NEAR_APOAPSIS_DEG |
15° | Angle from apoapsis to begin circularize |