GNC/com_guidance.py — CoM Guidance

Root of the guidance tower. Emits desired (pc,vc,ac)(\bm p_c,\bm v_c,\bm a_c) at each step by tracking monotonic progress ss along the discrete helix Λ={λi}i=1N\Lambda=\{\bm\lambda_i\}_{i=1}^N.

Startup Speed Ramp

Speed scales smoothly from rest; the ramp prevents an impulsive CoM demand at t=0t=0:

vd(t)=[1exp ⁣(t/τsu)]vrefv_d(t) = \Big[1 - \exp\!\big(-t/\tau_{\mathrm{su}}\big)\Big] v_{\mathrm{ref}}

(eq 5.1, final.tex §2.1)

With the ramp on, vd(0)=0v_d(0)=0; the centripetal seed ac(0)0\bm a_c(0)\approx\bm 0 is cached in a_c0 to warm-start [[analytic_feedforward]].

Monotonic Progress & Lookahead

Progress ss is strictly non-decreasing — once a segment is passed, guidance never walks back:

sk=max ⁣(sk1, proj(pcΛlocal))s_k = \max\!\big(s_{k-1},\ \mathrm{proj}(\bm p_c \to \Lambda_{\mathrm{local}})\big)

The reference point lies a lookahead time tlookt_{\mathrm{look}} ahead:

sref=sk+vdtlookΔss_{\mathrm{ref}} = s_k + \frac{v_d t_{\mathrm{look}}}{\Delta s}

Local search radius re-centers each step; full polyline scan runs once only.

Velocity Field: Direction Blend

At the lookahead reference, retrieve the unit tangent t^\hat{\bm t} and curvature κ\bm\kappa. Split the tracking error into along-track and lateral components:

e=ptrackpc,e=et^,e=eet^\bm e = \bm p_{\mathrm{track}} - \bm p_c,\quad e_{\parallel} = \bm e\cdot\hat{\bm t},\quad \bm e_{\perp} = \bm e - e_{\parallel}\hat{\bm t}

d=t^+ktracke,vcmd=sat ⁣(vdkprogresse)\bm d = \hat{\bm t} + k_{\mathrm{track}} \bm e_{\perp},\quad v_{\mathrm{cmd}} = \mathrm{sat}\!\big(v_d - k_{\mathrm{progress}} e_{\parallel}\big)

vc=vcmdd^\bm v_c = v_{\mathrm{cmd}} \hat{\bm d}

Centripetal Acceleration Feedforward

The output acceleration ac\bm a_c is the centripetal term required to hold the curved path at speed — not a position-error correction:

ac=vc2κ\bm a_c = \lVert\bm v_c\rVert^2 \bm\kappa

(eq 5.3, final.tex §2.2)

κ\bm\kappa is evaluated analytically from the spherical-helix parameterisation (no finite-difference ripple).

Analytic Tangent & Curvature

Helix parameter u[0,1]u\in[0,1]: θ=wθu\theta = w_\theta u, ϕ=ϕ0+wϕu\phi = \phi_0 + w_\phi u.

p(u)=R[cosϕcosθcosϕsinθsinϕ],t^=pp\bm p(u) = R\begin{bmatrix}\cos\phi\cos\theta\\\cos\phi\sin\theta\\\sin\phi\end{bmatrix},\qquad \hat{\bm t} = \frac{\bm p'}{\lVert\bm p'\rVert}

κ=1p2(pppp2p)\bm\kappa = \frac{1}{\lVert\bm p'\rVert^2} \left(\bm p'' - \frac{\bm p'\cdot\bm p''}{\lVert\bm p'\rVert^2} \bm p'\right)

(eqs 5.4–5.5, final.tex §2.2) p,p\bm p',\bm p'' follow analytically; θ,ϕ\theta,\phi are linear in uu.

Reference Smoothing

After the centripetal demand is formed, a low-pass filter stabilises the reference across steps:

vcsm=(1α)vcprev+αvc,acsm=vcsmvcprevΔt\bm v_c^{\mathrm{sm}} = (1-\alpha)\bm v_c^{\mathrm{prev}} + \alpha \bm v_c,\qquad \bm a_c^{\mathrm{sm}} = \frac{\bm v_c^{\mathrm{sm}} - \bm v_c^{\mathrm{prev}}}{\Delta t}

Both signals are saturated against vmaxv_{\max} and v˙max\dot v_{\max} from constraints.com. The smoothed ac\bm a_c replaces the curvature-based value so (p,v,a)(p,v,a) remain dynamically consistent.