chc.mintime¶
Stability tier: experimental.
Minimum-time (time-optimal) control via Pontryagin's minimum principle -- the double integrator.
For a control-affine plant with a bounded input, PMP makes the time-optimal control bang-bang: the
Hamiltonian is linear in u, so the optimum sits on a bound, u = -u_max * sign(switching fn),
switching when it changes sign. For the double integrator x'' = u, |u| <= u_max driven to
rest at the origin, that switching function is sigma = x + v|v|/(2 u_max) and the optimal
trajectory needs at most one switch (accelerate, then brake on the switching parabola).
The textbook complement to the quadratic-cost controllers in chc.control / chc.lqr:
minimise time to target, not a quadratic cost.
Scoped to the double integrator (general PMP is a costate two-point boundary-value problem); NumPy float64, and the sign-based law is non-differentiable, so it lives outside the JAX control core.
BangBangResult
dataclass
¶
A time-optimal rollout: the trajectory, the applied control, and its switch count.
switching_function(x, v, u_max)
¶
PMP switching function sigma = x + v|v|/(2 u_max); its sign picks the control.
bang_bang_control(x, v, u_max=1.0)
¶
Time-optimal feedback for the double integrator: -u_max sign(sigma), the <=1-switch law.
Off the switching curve -u_max sign(sigma); on it -u_max sign(v) (brake to the origin);
at the origin 0.
double_integrator_min_time(x0, v0, u_max=1.0)
¶
Closed-form minimum time to drive x''=u, |u|<=u_max, from (x0, v0) to the origin.
From rest (v0 = 0) this is the familiar 2 sqrt(|x0| / u_max).
bang_bang_rollout(x0, v0, u_max=1.0, *, dt=0.01)
¶
Open-loop time-optimal trajectory: bang u1 until the analytic switch time, then -u1.
Uses the closed-form switch time rather than a discrete sign(sigma) feedback, which would
chatter across the switching curve; this gives the clean at-most-one-switch trajectory PMP
predicts. Per-step integration is exact for the piecewise-constant control.