Skip to Content
ReferenceCLImaneuver

orbitforge maneuver

Synopsis

orbitforge maneuver --plan <PATH> [OPTIONS]

Description

Propagates a spacecraft through a sequence of burns and coast arcs, reporting what each burn cost in delta-v, propellant, and mass.

This executes a plan you supply. To solve for burn parameters that achieve a target, use target, which wraps this in a differential corrector.

Options

ParameterTypeUnitDefaultRequiredDescription
--planpathn/a—YesMission-plan JSON: epoch, initial orbit, thruster, tank, and burns. See the schema below.
--duration-hoursfloath6NoTotal propagation duration.
--step-secondsfloats60NoOutput sampling step.
--coaststringn/atwo-bodyNoCoast-arc force model: `two-body`, `j2`, `j4`, or `egm96[:DxO]` for embedded spherical harmonics.
--czmlpathn/a—NoWrite CZML with orbit and burn markers.
--oempathn/a—NoWrite the trajectory as a CCSDS OEM (KVN) file.
--jsonpathn/a—NoWrite the full mission result: samples and burn events.

Mission plan schema

{ "epoch": "2026-01-01T00:00:00Z", "initial_orbit": { "semi_major_axis_km": 6878.0, "eccentricity": 0.0, "inclination_deg": 51.6, "raan_deg": 0.0, "argument_of_perigee_deg": 0.0, "true_anomaly_deg": 0.0 }, "thruster": { "isp_s": 220.0, "max_thrust_n": 22.0 }, "tank": { "fuel_kg": 40.0, "dry_mass_kg": 240.0 }, "burns": [ { "type": "impulsive", "trigger": { "kind": "at_elapsed", "seconds": 600.0 }, "frame": "ric", "dv_mps": [0.0, 30.0, 0.0] }, { "type": "impulsive", "trigger": { "kind": "at_apoapsis", "orbit": 1 }, "frame": "ric", "dv_mps": [0.0, 29.0, 0.0] } ] }
SectionFieldsUnits
initial_orbitOsculating Keplerian elements at the epochkm, deg
thrusterisp_s, max_thrust_ns, N
tankfuel_kg, dry_mass_kgkg
burnsOrdered, non-overlapping, time-orderedsee below

Burn triggers

kindFires
at_epochAt an absolute epoch within the window
at_elapsedseconds after the mission epoch
at_apoapsisAt the orbit-th apoapsis after the previous burn
at_periapsisAt the orbit-th periapsis after the previous burn

Time triggers are absolute along the mission timeline. Orbit-event triggers are resolved relative to the state left by the previous burn, counted 1-based and strictly after that point.

That relative behavior is what makes a multi-burn sequence composable: the second burn of a transfer fires at the apoapsis the first burn created, without you having to compute when that occurs.

Burn types

typeFieldsModels
impulsiveframe, dv_mps as a 3-vectorAn instantaneous velocity change
finiteframe, direction, thrust_n, duration_sConstant thrust over a real duration

Impulsive burns are the right model when the burn is short compared with the orbital period. Finite burns matter for low-thrust systems, where the spacecraft moves substantially during the burn and the impulsive approximation overstates what the burn achieves.

Worked example

A two-burn raise, in the style of a Hohmann transfer:

orbitforge maneuver \ --plan plan.json \ --duration-hours 4 --step-seconds 60 \ --json mission.json
Propagated 2 burns over 4.0 h: total delta-v 59.00 m/s, propellant 7.553 kg, final mass 272.447 kg. burn 0 (impulsive, ric): t=600.0 s, dv=30.00 m/s, propellant=3.867 kg, mass_after=276.133 kg burn 1 (impulsive, ric): t=3472.4 s, dv=29.00 m/s, propellant=3.687 kg, mass_after=272.447 kg

Reading the output

FigureValueMeaning
Total delta-v59.00 m/sSum of both burns
Propellant7.553 kgTotal consumed, via the rocket equation
Final mass272.447 kg280 kg wet mass less propellant burned
Burn 0t=600.0 sFired exactly when the at_elapsed trigger asked
Burn 1t=3472.4 sResolved from the at_apoapsis trigger

The apoapsis trigger did the work

Burn 1 was never given a time. It was told to fire at the first apoapsis after burn 0, and the propagator resolved that to 3472.4 seconds.

That figure is itself a check on the physics: burn 0 raised apoapsis at 600 s, and half an orbital period later the spacecraft arrives there. The 2872-second gap is consistent with roughly half the period of the transfer ellipse created by the first burn.

Propellant falls per burn, for a real reason

Burn 0 consumed 3.867 kg for 30 m/s; burn 1 consumed 3.687 kg for 29 m/s. The second burn is not simply cheaper because it is smaller. Propellant per unit delta-v scales with current mass, and the vehicle is lighter after burn 0:

Δm=m(1−e−Δv/(Ispg0))\Delta m = m \left(1 - e^{-\Delta v / (I_{sp} g_0)}\right)

At 276.133 kg rather than 280 kg, the same delta-v costs proportionally less propellant. This is why delta-v, not propellant mass, is the currency of mission design: delta-v is a property of the trajectory, while propellant depends on the mass you happen to be carrying at the time.

Coast-arc fidelity

--coast sets the force model between burns, and it defaults to two-body.

SettingUse
two-bodyShort missions, first-order checks
j2 or j4Anything spanning more than a few orbits
egm96[:DxO]High-fidelity work with embedded spherical harmonics

A two-body coast arc is a poor model for a plan spanning many orbits. J2 causes the orbit plane to regress and the line of apsides to rotate, so an at_apoapsis trigger many orbits out will fire at a different place than two-body predicts. Raise the coast fidelity before trusting long sequences.

See also

  • target to solve for burn parameters instead of specifying them.
  • stationkeep for long-horizon delta-v budgets.
Question? Give us feedbackDocuments Varaha Constellation Designer main (pre-release)
Last updated on