Skip to content

08. Goddard problem with a knot

Example 07 used one polynomial across the thrust switch at burnout, causing oscillations. Splitting time near that switch lets each phase use its own polynomial. The physical model is unchanged.

ItemDefinition
StatesRadial height hh, velocity vv, mass mm
ControlThrust TT
ObjectiveMaximize final height
PhasesTwo phases, 25 nodes each; knot fixed at 0.075, final time free
New conceptsKnots and discontinuous controls

The rocket and objective are the same as Example 07. Its thrust changes from maximum through an intermediate singular arc to zero. The one-phase solution burns out around 0.077, so we place a knot at 0.075:

  • Phase 1: 0≤t≤0.0750\le t\le0.075, primarily powered ascent.
  • Phase 2: 0.075≤t≤tf0.075\le t\le t_f, primarily coasting.

These roles are encouraged by the initial guess; the thrust constraints themselves are the same in both phases. All quantities remain dimensionless.

Both phases use

h˙=v,v˙=T−D(h,v)m−g(h),m˙=−Tc,\dot h=v,\qquad\dot v=\frac{T-D(h,v)}m-g(h),\qquad\dot m=-\frac Tc, D=Dcv2exp⁡ ⁣(−Hch−h0h0),g=g0(h0h)2.D=D_cv^2\exp\!\left(-H_c\frac{h-h_0}{h_0}\right),\qquad g=g_0\left(\frac{h_0}h\right)^2.

See Example 07 for the meaning of each term.

t1=0.075,h(1)(t1)=h(2)(t1),v(1)(t1)=v(2)(t1),m(1)(t1)=m(2)(t1).t_1=0.075,\qquad h^{(1)}(t_1)=h^{(2)}(t_1),\quad v^{(1)}(t_1)=v^{(2)}(t_1),\quad m^{(1)}(t_1)=m^{(2)}(t_1).

States are continuous, but no thrust continuity condition is imposed. Thrust may jump at the knot.

h(0)=1,v(0)=0,m(0)=1,v(tf)=0,m(tf)=0.6.h(0)=1,\quad v(0)=0,\quad m(0)=1,\qquad v(t_f)=0,\quad m(t_f)=0.6. 0≤T≤3.5,h≥1,v≥0,0.6≤m≤1,0\le T\le3.5,\quad h\ge1,\quad v\ge0,\quad0.6\le m\le1, t1≥0.05,tf≥0.1,J=−h(tf).t_1\ge0.05,\qquad t_f\ge0.1,\qquad J=-h(t_f).

The knot lower bound is inactive because the equality already fixes t1t_1.

The parameters match Example 07: h0=g0=m0=1h_0=g_0=m_0=1, Dc=310D_c=310, Hc=500H_c=500, c=0.5c=0.5, Tmax⁡=3.5T_{\max}=3.5, and mf=0.6m_f=0.6, with the additional knot time 0.075.

Start with phase times 0→0.1→0.30\to0.1\to0.3; optimization moves the knot to 0.075. Height is cubic from 1 to 1.01 and velocity is zero. Mass decreases linearly from 1 to 0.6 in phase 1, then remains 0.6. Thrust starts at maximum throughout phase 1 and zero throughout phase 2.

Height, velocity, mass, and thrust. Blue and orange are the two phases with 25 nodes each. The vertical dashed line marks t = 0.075; red dotted lines mark dry mass and maximum thrust.
Height, velocity, mass, and thrust. Blue and orange are the two phases with 25 nodes each. The vertical dashed line marks t = 0.075; red dotted lines mark dry mass and maximum thrust.
The ascent trail is colored by phase. Velocity and thrust histories show the knot and the current time.
  • Final height: 1.0128, close to Example 07’s 1.0128.
  • Thrust drops discontinuously at the knot and remains nearly zero throughout phase 2.
  • Mass at the end of phase 1: 0.6000, so almost all propellant is consumed in that phase.
  • Final time: 0.200.

The discontinuity now lies between the final node of phase 1 and the first node of phase 2. Within each phase, thrust is smooth enough for a polynomial. Phase 2 can represent zero thrust directly. Phase 1 also has fewer demands on its polynomial, reducing oscillation around the maximum-to-intermediate transition.

This example fixes the knot based on the previous solution. It is slightly earlier than the one-phase burnout estimate 0.079, which makes the rocket consume propellant earlier and slightly reduces final height, around the fifth decimal place. The late rise in phase-1 thrust is consistent with burning the remaining propellant before the fixed knot.

Removing t1=0.075t_1=0.075 allows the optimizer to choose the knot. Additional conditions, such as consuming propellant by the end of phase 1, may be needed to keep it aligned with burnout.

  • Change result.equal(ts0, 0.075) to 0.06 or 0.09. An earlier knot may reduce height; a later one may put the thrust jump inside phase 1 and restore oscillations.
  • Reduce [25, 25] to [15, 10] and compare accuracy with the 50-node one-phase solution.
  • Remove the knot-time equality and inspect the optimized knot and thrust history.
Terminal window
uv run python examples/08_goddard_1knot.py

View the Python source on GitHub.