Moduł 07 · Optymalizacja trajektorii

Optymalizacja trajektorii

CHOMP, STOMP, ITOMP, TrajOpt (SCO), GuSTO, direct collocation, multiple shooting, GPMP2, KOMO. Solvery (IPOPT, SNOPT, OSQP).

TL;DR

Planery próbkowe (moduł 06) zwracają jakąś ścieżkę (probabilistically complete), ale często daleką od optymalnej. Planery optymalizacyjne startują od pełnej wstępnej trajektorii (np. linia prosta start→goal) i deformują ją minimalizując zadaną funkcję kosztu: gładkość, odległość od przeszkód, energię, czas.

  • CHOMP (Ratliff 2009) — gradient descent na J(ξ)=wsJsmooth+woJobsJ(\xi) = w_s J_{\text{smooth}} + w_o J_{\text{obs}} z analitycznym gradientem SDF (moduł 03). Centerpiece tego modułu.
  • STOMP (Kalakrishnan 2011) — gradient-free, sample K rolloutów per iteracja + ważenie eksponencjalne. Działa dla niegładkich funkcji kosztu (np. binarna kolizja).
  • TrajOpt / SCO (Schulman 2013) — SQP z trust region; constraints traktowane jako penalty z adaptacyjnym współczynnikiem. Bardziej rygorystyczne podejście, profesjonalne implementacje.
  • GPMP, GPMP2 (Mukadam 2017) — Gaussian Process Motion Planning: trajektoria jako GP belief, inferencja Bayesowska. Naturalny gradient + niepewność.
  • KOMO (Toussaint) — k-order Markov optimization, elastyczna składnia constraints w czasie dla complex manipulation.
  • Direct methods (single/multiple shooting, collocation) — sformułowania klasycznej teorii sterowania. Solvery: IPOPT, SNOPT, CasADi.

Wspólny mianownik: NLP / QP w wysokim wymiarze (NdN \cdot d zmiennych, gdzie NN = liczba waypointów ~30-100, dd = wymiar C-space — dla Pandy 7). Sukces optymalizatora zależy od inicjalizacji, funkcji kosztu i solvera.

Sformułowanie NLP

Trajektoria parametryzowana jako wektor waypointów ξ=[q0,q1,,qN]R(N+1)d\xi = [q_0, q_1, \ldots, q_N]^\top \in \mathbb{R}^{(N+1)d}. Zadanie:

minξ  J(ξ)=tL(qt,q˙t)s.t.q0=qs,  qN=qg,  h(qt)0\min_{\xi} \; J(\xi) = \sum_t L(q_t, \dot q_t) \quad \text{s.t.} \quad q_0 = q_s, \; q_N = q_g, \; h(q_t) \leq 0

gdzie LL to lokalny lagranżjan (smoothness, energy, clearance), hh to ograniczenia (kolizja, joint limits, dynamika).

Inicjalizacja krytyczna — typowo linia prosta w C-space lub ścieżka z RRT (warm start dla optymalizacji = hybrydowe planery: sample + optimize).

Typowe człony funkcji kosztu:

  • Smoothness: q¨2\|\ddot q\|^2 lub q...2\|\dddot q\|^2 (jerk-minimal trajektorie).
  • Obstacle: cobs(q)=max(0,ϵΦ(q))2q˙c_{\text{obs}}(q) = \max(0, \epsilon - \Phi(q))^2 \cdot |\dot q| — kara aktywna gdy Φ(q)<ϵ\Phi(q) < \epsilon (przeszkoda bliżej niż margines), waga proporcjonalna do prędkości (kara rośnie gdy szybko przelatuje).
  • Energy: tτt2\sum_t \|\tau_t\|^2 dla trajektorii dynamicznej (wymaga inwersji dynamiki).
  • Time: TT (długość trajektorii).
  • Manipulability: w(q)-w(q) by trzymać się dalej od singularności (moduł 02).

CHOMP — Covariant Hamiltonian Optimization

CHOMP łączy dwa pomysły:

  1. Funkcjonalny gradient — traktuje trajektorię jako element przestrzeni funkcyjnej, liczy gradient kosztu względem niej. Dla obstacle term — dosłownie Φ(qt)-\nabla \Phi(q_t) (kierunek „uciekania" od przeszkód, moduł 03).
  2. Covariant preconditioning — gradient mnożony przez M1M^{-1} gdzie MM to Hessian smoothness term. Daje to lepszą zbieżność i naturalnie propaguje zmiany jednego waypointa na sąsiednie (efekt „guma ciągnie").

Update rule (uproszczony, bez covariant preconditioning):

ξ(k+1)=ξ(k)αJ(ξ(k))\xi^{(k+1)} = \xi^{(k)} - \alpha \cdot \nabla J(\xi^{(k)})

Gdzie gradient na i-tym waypoincie:

tJ=ws[(qt12qt+qt+1)]+wo2(ϵΦ(qt))(Φ(qt))q˙t\nabla_t J = w_s \cdot [-(\, q_{t-1} - 2 q_t + q_{t+1} \,)] + w_o \cdot 2(\epsilon - \Phi(q_t)) \cdot (-\nabla \Phi(q_t)) \cdot |\dot q_t|

Pierwszy człon (smoothness): negatywny dyskretny Laplacian — siła ciągnąca qtq_t ku średniej z sąsiadów (linia prosta jest jego minimum). Drugi (obstacle): siła odpychająca proporcjonalna do głębokości w pasie bezpieczeństwa.

W demo poniżej: obserwuj trajektorię deformującą się od linii prostej do zakrzywionej krzywej omijającej przeszkody. Strzałki J-\nabla J na każdym waypoincie pokazują kierunek update. Ghost'y co 8 iteracji — historia deformacji. Suwaki ws,wo,εw_s, w_o, \varepsilon w czasie rzeczywistym przeliczają cały bieg.

Eksperymenty do wypróbowania:

  • Zwiększ wow_o z 15 do 35 — trajektoria odsuwa się dalej od przeszkód, ale wydłuża.
  • Zmniejsz wsw_s do 0.3 — trajektoria może mieć widoczne „zygzaki", smooth term mniej dominuje.
  • Zwiększ ε\varepsilon z 0.06 do 0.12 — większy margines bezpieczeństwa, krzywa znacznie szerszy łuk wokół przeszkód.

CHOMP — iter 0 / 80

⟳ iterating
Trajektoria w 2D — deformacja gradient descent
SG
Koszt vs iteracja
smoothness:
0.0000
obstacle:
0.0079
total:
0.0079
smoothnessobstacletotal
w_smooth (λsmooth\lambda_{\text{smooth}})1.00
w_obs (λobs\lambda_{\text{obs}})15.0
ε (margines)0.060

Wariant Incremental CHOMP

Online'owy wariant: re-run optymalizacji po każdej iteracji sterownika, z warm-start poprzednią trajektorią + horyzontowym odcięciem. Łączy planowanie + sterowanie. Konkurencja MPC (moduł 10) — różnica: CHOMP iteruje gradient descent dla pełnej trajektorii, MPC rozwiązuje QP nad krótkim horyzontem.

STOMP — Stochastic Trajectory Optimization

CHOMP wymaga różniczkowalnej funkcji kosztu — gradient musi istnieć. W praktyce niektóre koszty są nieróżniczkowalne:

  • Binarny collision check (FCL zwraca true/false, brak gradientu)
  • Niefizyczne koszty (np. „odległość od demonstracji eksperta" liczona przez DTW)
  • Koszty oparte na nauczonych modelach (sieć neuronowa może mieć gradient szumowy)

STOMP omija to przez gradient-free sampling. Algorytm:

for iter = 0..maxIter:
  for k = 1..K:                              # K rolloutów
    ε_k ~ N(0, Σ)                            # zaszumiona perturbacja
    ξ_k = ξ + ε_k                            # zaszumiona trajektoria
    J_k = cost(ξ_k)                          # ewaluacja (callbox)
  w_k = exp(-J_k / λ) / Σ_j exp(-J_j / λ)    # softmax wag
  ξ ← ξ + Σ_k w_k · ε_k                      # update jako średnia ważona

Kluczowe parametry:

  • KK (typowo 10-30) — liczba rolloutów per iteracja. Więcej = lepsza estymacja gradientu, ale wolniej.
  • σ\sigma — odchylenie standardowe szumu. Większe = szersza eksploracja.
  • λ\lambda — temperatura softmax. Małaλ\lambdagreedy (dominuje 1-2 najlepsze rollouty); duża ⇒ uśrednianie po wielu (eksploracja).

Macierz kowariancji Σ\Sigma wybierana tak, by szum był skorelowany wzdłuż trajektorii — pojedyncze waypointy nie przesuwają się niezależnie, tylko całe „odcinki" (gładkie perturbacje). Typowo Σ=(AA)1\Sigma = (A^\top A)^{-1} gdzie AA macierz drugiej różnicy (=Hessian smoothness).

STOMP — iter 0 / 35

best cost: 0.0841
SG
K (rollouts)20
σ szumu0.040
λ (temperatura)0.020
Co zobaczyć: chmura cienkich linii = K rolloutów (zaszumionych perturbacji bieżącej trajektorii). Kolor i nasycenie kodują wagę: jasny niebiesko-zielony = wysoka waga (niski koszt), szary = niska waga. Fioletowa gruba linia = bieżąca mean trajectory. λ kontroluje „chciwość": mała λ ⇒ dominuje 1-2 najlepsze rollouty (greedy); duża λ ⇒ uśrednianie po wielu (eksploracja). Suwak σ szumu — większy = więcej eksploracji, ale i więcej rolloutów w kolizji.

STOMP vs CHOMP — kiedy które

  • CHOMP szybsze gdy gradient jest dostępny i tani; wymaga gładkości.
  • STOMP wolniejsze (każda iteracja = K ewaluacji), ale działa dla dowolnej (czarno-skrzynkowej) funkcji kosztu. Trywialnie parallelizuje się (każdy rollout osobno).
  • Hybryda ITOMP — CHOMP wewnątrz, STOMP do rozwiązywania perturbacji przy lokalnych minimach.

TrajOpt / SCO — SQP z penalty constraints

TrajOpt (Schulman, Ho, Lee, Awwal, Bradlow, Abbeel; 2013) używa Sequential Convex Optimization (SCO) — kolejne lokalne convex aproksymacje pełnego nieliniowego problemu.

Każda iteracja:

  1. Linearyzuj nielinearne constraints wokół bieżącej trajektorii ξ(k)\xi^{(k)}.
  2. Wyminimum convex problem (QP) wewnątrz trust region ξξ(k)δ\|\xi - \xi^{(k)}\| \leq \delta.
  3. Sprawdź czy lokalna predykcja zgadzała się z prawdziwym kosztem — jeśli tak, zwiększ δ\delta; jeśli nie, zmniejsz i powtórz.

Kluczowy trick — penalty z adaptacyjnym μ: constraints kolizji przekształcamy w karę μtviol(qt)\mu \sum_t \mathrm{viol}(q_t) z dużym μ\mu. Gdy iteracja produkuje feasible trajektorię, μ\mu nie rośnie; gdy nie — podwajamy. Konwergencja w kilku-kilkunastu zewnętrznych iteracjach.

GuSTO (Bonalli 2019) — ulepszenie SCO z lepszymi gwarancjami zbieżności (trust-region SQP z line-search).

TrajOpt SCO — iter 0 / 72

δ = 0.050 · μ = 1.0 · trust =
smooth
0.0000
μ · obstacle
0.0101
total
0.0101
Co zobaczyć: Pomarańczowy okrąg wokół każdego waypoint'a to trust region δ — limit ‖Δξ_i‖ per iteracja. Obserwuj: gdy linearyzacja jest dobra (actual ≈ predicted), δ rośnie (trust ↑) — pozwalamy na większe kroki. Gdy linearyzacja zawodzi (np. nagła zmiana SDF przy obstacle), δ maleje (trust ↓).Outer loop: μ — kara za narusznie obstacle. Mała μ na początku → solver eksploruje. Po każdym sukcesie inner loop: μ podwajane jeśli wciąż feasibility violated. Standard Schulman 2013.

Trzy kluczowe różnice TrajOpt vs CHOMP

  • Constraint handling: CHOMP używa soft penalty w funkcji kosztu (gradient z miękkim odpychaniem). TrajOpt traktuje obstacle jako hard constraintz adaptive μ — gwarancja feasibility w limicie.
  • Trust region: CHOMP zaufa pełnemu gradient step'owi (z fixed learning rate). TrajOpt weryfikuje czy linearyzacja była dobra — jeśli nie, zmniejsza krok. Sprawia że TrajOpt rzadziej dywerguje.
  • Konwergencja: CHOMP O(N) iteracji do konwergencji. TrajOpt O(log(1/ε)) outer + O(N) inner — wykładniczo szybsza w pobliżu rozwiązania, kosztem droższej pojedynczej iteracji (QP solve).

Direct methods — single/multiple shooting, collocation

Z teorii sterowania optymalnego — sposób dyskretyzacji ciągłego problemu OCP (Optimal Control Problem). Wszystkie trzy mają wady i zalety:

MetodaZmienne decyzyjneZaletyWady
Single shootingTylko sekwencja sterowań u0,u1,,uN1u_0, u_1, \ldots, u_{N-1}; stany xtx_t liczone przez forward simulation.Mało zmiennych. Dla krótkich horyzontów dobre.Numerycznie niestabilne dla długich horyzontów (małe zmiany u0 dają duże zmiany xN).
Multiple shootingSekwencja par (xk,uk)(x_k, u_k), z continuity constraints xk+1=f(xk,uk)x_{k+1} = f(x_k, u_k) jako równania równościowe.Stabilne, sparse Jacobian — solver wykorzystuje strukturę.Więcej zmiennych decyzyjnych.
CollocationTrajektoria parametryzowana wielomianami; równania dynamiki narzucone w punktach kolokacji.Wysokie rzędy zbieżności (Radau, Lobatto); dobre dla smooth problems.Skomplikowana implementacja; gorsze dla nieróżniczkowalnych dynamics.

Frameworki: CasADi (Python/MATLAB symbolic OCP), acados (real-time MPC), drake (Robot Locomotion Group, MIT).

GPMP, KOMO — alternatywne sformułowania

GPMP / GPMP2 (Mukadam et al. 2017)

Gaussian Process Motion Planning. Trajektoria jako Gaussian Process:

ξ(τ)GP(μ(τ),K(τ,τ))\xi(\tau) \sim \mathcal{GP}(\mu(\tau), K(\tau, \tau'))

Optymalizacja staje się inferencją Bayesowską — MAP estimate likelihood × prior. Prior to gładkość (kernel KK), likelihood to obstacle cost. Naturalna interpretacja niepewności + efektywna implementacja przez factor graph. Zalety: ciągła reprezentacja trajektorii (sample w dowolnej chwili), wsparcie dla warm-start z poprzedniego planu.

KOMO (Toussaint)

K-Order Markov Optimization — generalizacja, gdzie funkcja kosztu może zależeć od k kolejnych waypointów (k-tego rzędu Markov). Pozwala na elastyczne wyrażanie zadań manipulacyjnych jako constraints temporalnych („w chwili t = T/2 chwytak musi być nad obiektem", „kontakt musi się utrzymywać przez >t1 do t2<"). Używane w TAMP (Task and Motion Planning, moduł 17).

Solvery dla NLP trajektorii

SolverTypWnętrzeMocne stronyLicencja
IPOPTNLPInterior pointRobustny dla problemów średniej wielkości, popularny w badaniach. Wymaga gradientów (Hessian opcjonalnie).EPL (open)
SNOPTNLPSQPNiezawodny dla problemów rzeczywistych (skomplikowane constraints). Standard w aerospace.komercyjna
OSQPQPADMMBardzo szybkie dla QP — MPC produkcyjne, do 10 kHz na CPU. Embedded code generation (C).Apache 2.0
CasADiframeworkAD + wrapperySymbolic AutoDiff + dostęp do IPOPT, SNOPT, qpOASES, HPIPM. Python/MATLAB/C++ frontend. Standard dla OCP w badaniach.LGPL
Ceresleast squaresLevenberg-Marquardt + trust regionOptymalny dla problemów typu „suma kwadratów" (bundle adjustment, SLAM, calibration). AutoDiff w C++.BSD (Google)
FORCES ProNLP/QPCode generationEmbedded MPC (auto, drony) — generuje wyspecjalizowany kod C dla konkretnego problemu, ms-level performance.komercyjna
qpOASESQPActive setIdealny dla MPC z warm-start (poprzednia iteracja jako initial active set). Embedded-friendly.LGPL

Reguła kciuka: dla badań/prototypu → CasADi + IPOPT (Python, łatwy do napisania). Dla produkcyjnego MPC → qpOASES albo OSQP (embedded C). Dla CHOMP/TrajOpt → własna implementacja Levenberg-Marquardt lub PCG (preconditioned conjugate gradient) wystarcza.

Optymalizacja trajektorii na Pandzie 7D

Demo CHOMP/STOMP w naszym module operuje na 2D dla intuicji. Na realnej Pandzie 7-DOF:

  • Trajektoria: ξR30×7\xi \in \mathbb{R}^{30 \times 7} dla N=30 waypointów. Wymiar problemu: 210 zmiennych.
  • Obstacle cost: SDF sceny + sphere SDF na ogniwach Pandy (sprawdzanie kolizji + gradient).
  • Czas: CHOMP zwykle 0.1-0.5s dla typowego pick&place; TrajOpt 0.5-2s.
  • Jakość: lepsze (gładsze, krótsze) niż RRT-Connect, kosztem czasu. W moduł 18 (benchmark) — porównanie 50 zadań Pandy: RRT-Connect vs CHOMP vs BIT*.

Ściąga

Anatomia funkcji kosztu

J(ξ)=wsJsmooth(ξ)+woJobs(ξ)+[weJenergy+wtT+]J(\xi) = w_s J_{\text{smooth}}(\xi) + w_o J_{\text{obs}}(\xi) + [w_e J_{\text{energy}} + w_t T + \ldots]
  • smoothness: q¨2\|\ddot q\|^2 lub q...2\|\dddot q\|^2
  • obstacle: max(0,ϵΦ)2q˙\max(0, \epsilon - \Phi)^2 \cdot |\dot q|
  • energy: τ2\|\tau\|^2
  • time: TT

CHOMP update (jednowierszowo)

ξ(k+1)=ξ(k)αM1J(ξ(k))\xi^{(k+1)} = \xi^{(k)} - \alpha \, M^{-1} \, \nabla J(\xi^{(k)})

M=AAM = A^\top A (Hessian smoothness) — covariant preconditioning. Endpoints zafiksowane.

STOMP update

ξ(k+1)=ξ(k)+k=1Kwkϵk,wk=exp(Jk/λ)jexp(Jj/λ)\xi^{(k+1)} = \xi^{(k)} + \sum_{k=1}^K w_k \, \epsilon_k, \quad w_k = \frac{\exp(-J_k/\lambda)}{\sum_j \exp(-J_j/\lambda)}

TrajOpt / SCO

SQP z trust region + adaptive μ dla constraints jako penalty. Zewnętrzna pętla powiększa μ aż feasibility osiągnięte.

Solvery

  • NLP: IPOPT (open), SNOPT (komercyjna)
  • QP: OSQP, qpOASES — embedded MPC
  • Framework: CasADi (AutoDiff + wszystkie solvery)

Referencje

  • Ratliff, Zucker, Bagnell, Srinivasa, „CHOMP: Gradient Optimization Techniques for Efficient Motion Planning" (ICRA 2009).
  • Kalakrishnan, Chitta, Theodorou, Pastor, Schaal, „STOMP: Stochastic Trajectory Optimization for Motion Planning" (ICRA 2011).
  • Schulman, Ho, Lee, Awwal, Bradlow, Abbeel, „Finding Locally Optimal, Collision-Free Trajectories with Sequential Convex Optimization" (RSS 2013) — TrajOpt.
  • Mukadam, Dong, Yan, Dellaert, Boots, „Continuous- time Gaussian Process Motion Planning via Probabilistic Inference" (IJRR 2018) — GPMP2.
  • Toussaint, „Newton methods for k-order Markov Constrained Motion Problems" (2014) — KOMO.
  • Wächter & Biegler, „On the implementation of an interior-point filter line-search algorithm for large-scale nonlinear programming" (Math. Prog. 2006) — IPOPT.
  • Stellato, Banjac, Goulart, Bemporad & Boyd, „OSQP: An Operator Splitting Solver for Quadratic Programs" (Math. Prog. Comp. 2020).
  • Andersson, Gillis, Horn, Rawlings, Diehl, „CasADi — a software framework for nonlinear optimization and optimal control" (Math. Prog. Comp. 2019).