Skip to content

02. Accelerate and stop

Move a stationary cart 10 m and stop exactly at the destination. Acceleration is limited to ±2 m/s². When should you accelerate, and when should you brake, to arrive as soon as possible?

ItemDefinition
StatesPosition xx, velocity vv
ControlAcceleration aa
ObjectiveMinimize arrival time tft_f
PhasesTwo phases, 12 nodes each; free knot and final times
New conceptsTwo states, control bounds, and phase splitting

Example 01 chose velocity directly. A real vehicle instead controls acceleration. Velocity accumulates from acceleration and cannot change instantly, so both position and velocity are states. Braking too early wastes time; braking too late overshoots the destination.

x˙=v,v˙=a.\dot{x}=v,\qquad\dot{v}=a.

There is no friction or drag. The control affects position through two successive integrations.

x(0)=0,v(0)=0,x(tf)=10,v(tf)=0.x(0)=0,\quad v(0)=0,\qquad x(t_f)=10,\quad v(t_f)=0.

The final time is unknown.

−2≤a≤2.-2\le a\le2.

Positive acceleration speeds up the cart; negative acceleration brakes it. The same bounds apply in both phases.

Split time at an unknown t1t_1. Position and velocity are continuous at the knot, but acceleration may jump. The optimum has one acceleration switch, so the knot can represent it exactly.

J=tf.J=t_f.
SymbolParameterValue
ddPARAMETERS["distance"]10 m
amax⁡a_{\max}PARAMETERS["max_acceleration"]2 m/s²

Use phase times 0→3→60\to3\to6 s, position linear from 0 to dd, constant velocity d/6d/6, and zero acceleration. This does not satisfy the zero endpoint velocities. The solver adjusts times, states, and controls to satisfy them and shorten the motion.

Position, velocity, and acceleration. Blue and orange show acceleration and braking phases, with 12 nodes each. Black dashed curves are analytic; the gray vertical line marks the knot, and red dotted lines mark ±2 m/s².
Position, velocity, and acceleration. Blue and orange show acceleration and braking phases, with 12 nodes each. Black dashed curves are analytic; the gray vertical line marks the knot, and red dotted lines mark ±2 m/s².
Cart motion on the left, with its trail colored by phase. Velocity and acceleration histories on the right show the current time with a vertical cursor.
  • Arrival time: 4.472 s, agreeing with 25=2\sqrt5= 4.472 s.
  • Switching time: 2.236 s, at position 5.00 m and peak velocity 4.472 m/s.
  • Acceleration is +2+2 throughout phase 1 and −2-2 throughout phase 2. The velocity history is triangular.

Why maximum acceleration and maximum braking?

Section titled “Why maximum acceleration and maximum braking?”

The area under the velocity curve is distance, fixed at 10 m. We want that area with the smallest possible width in time. The curve must start and finish at zero, and its slopes cannot exceed ±2\pm2. The narrowest possible shape is a triangle with the steepest allowed rise and fall. A trapezoid or rounded curve needs more time for the same area.

A control that stays at one bound or the other and switches between them is bang-bang control (indirect derivation).

Symmetry places the switch at x=d/2x=d/2. From amax⁡t12/2=d/2a_{\max}t_1^2/2=d/2,

t1=damax⁡,tf=2damax⁡=25.t_1=\sqrt{\frac{d}{a_{\max}}},\qquad t_f=2\sqrt{\frac{d}{a_{\max}}}=2\sqrt5.

Peak velocity is d amax⁡=20\sqrt{d\,a_{\max}}=\sqrt{20} m/s.

A smooth polynomial cannot represent the acceleration jump accurately and oscillates near it. With a knot at the switch, acceleration is constant in each phase and position and velocity remain continuous (multiple phases).

  • Set distance to 40. Arrival time doubles to 240/2≈8.942\sqrt{40/2}\approx8.94 s: quadrupling distance doubles time.
  • Change the time guess from Problem([0, 3, 6], ...) to Problem([0, 1, 6], ...). The solver may report success with a knot near 1.32 s, a switch spread across several nodes within phase 2, and duration about 4.50 s. This shows why knot placement matters.
  • Call solve(nodes=4) instead of solve(). The phasewise polynomial solution remains accurate with fewer nodes.
Terminal window
uv run python examples/02_move_stop.py

View the Python source on GitHub.