Moduł 10 · MPC i bezpieczeństwo

Sterowanie predykcyjne i online planning

Linear MPC, NMPC, MPPI, Tube/Log/Smooth MPPI, STORM, DDP, iLQR, iLQG, Crocoddyl, CEM, real-time iteration, warm-starting.

TL;DR

Model Predictive Control (MPC) łączy planowanie i sterowanie w jednym mechanizmie: w każdym kroku sterowania rozwiązuj optimization problem dla N kroków przyszłości, zastosuj tylko pierwszy control, powtórz. Ta strategia receding horizon daje:

  • Adaptacyjność — automatyczne uwzględnienie zaburzeń (każda iteracja widzi aktualny stan).
  • Constraint handling — ograniczenia naturalnie wchodzą w QP/NLP.
  • Prediction — system „widzi" przyszłość N kroków, reaguje zanim coś się stanie.

Rodziny MPC:

  • Linear MPC — model liniowy xk+1=Axk+Bukx_{k+1} = A x_k + B u_k, koszt kwadratowy. QP per krok, fast (μs).
  • NMPC — model nieliniowy, NLP per krok. Wolniejsze (ms), ale obsługuje dynamiki manipulatora.
  • iLQR / DDP / iLQG — wykorzystują strukturę dynamiczną (Bellman + backward pass) — szybsze niż NMPC dla długich horyzontów.
  • Sampling-based MPC (MPPI, CEM) — gradient-free, K rolloutów + weighted update. Działa dla nieróżniczkowalnych kosztów.
  • Tube MPC, Robust MPC — gwarantują stabilność przy bounded disturbances.

Linear MPC — fundament

Załóżmy liniowy model w postaci dyskretnej:

xk+1=Axk+Buk,xkRn,  ukRmx_{k+1} = A x_k + B u_k, \quad x_k \in \mathbb{R}^n, \; u_k \in \mathbb{R}^m

Problem MPC dla horyzontu NN i bieżącego stanu x0x_0:

minu0,,uN1  k=0N1[xkQxk+ukRuk]+xNQfxN\min_{u_0, \ldots, u_{N-1}} \; \sum_{k=0}^{N-1} \big[ x_k^\top Q x_k + u_k^\top R u_k \big] + x_N^\top Q_f x_N

s.t. xk+1=Axk+Buk,ukU,  xkXx_{k+1} = A x_k + B u_k, \quad u_k \in \mathcal{U}, \; x_k \in \mathcal{X}.

Po stackingu predykcji to standard QP:

minu12uHu+gus.t.  Ainequb\min_u \tfrac{1}{2} u^\top H u + g^\top u \quad \text{s.t.} \; A_{\text{ineq}} u \leq b

Rozwiązuje się przez aktywne zbiory (qpOASES), interior point (OSQP) lub embedded code generation (FORCES Pro, μ-controller). Typowy czas: 1-100 μs dla N=20, n=10, m=4 → 1-100 kHz update rate na CPU.

Stabilność

Klasyczne wyniki (Mayne et al. 2000): Linear MPC z terminal cost xNPxNx_N^\top P x_N gdzie PP = solution of discrete algebraic Riccati equation + terminal set constraint daje gwarantowaną stabilność asymptotyczną.

W praktyce: zaniedbywane (terminal cost = LQR P) gdy horyzont długi.

Linear MPC — point mass tracking (t = 0.00 s, N = 20)

1.00.0-1.00s10spos
horizon NN20
reference
referenceactual (executed)predicted (N kroków)horyzont planowania
Co zauważyć: żółty obszar to horyzont planowania — przy każdym kroku MPC rozwiązuje QP dla tych N kroków przyszłości, ale stosuje TYLKO pierwszy control. Następny krok — re-plan z nowego stanu (receding horizon). Pomarańczowa przerywana to predykcja w chwili t; niebieska gruba to to, co faktycznie się wydarzyło. Krótkie N (≤ 5) — niestabilne, niebieska linia goni z opóźnieniem. Długie N (30+) — gładsze tracking, ale rośnie koszt obliczeniowy. Spróbuj zmienić reference na step żeby zobaczyć jak MPC „widzi" przyszłą zmianę z wyprzedzeniem.

Receding horizon — czemu zawsze re-plan

W każdym kroku MPC rozwiązuje QP dla N kroków przyszłości, ale aplikuje tylko pierwszy. To pozwala na:

  • Disturbance rejection — następny krok widzi aktualny stan, nie przewidywany.
  • Model mismatch correction — błędy modelu automatycznie kompensowane przez feedback.
  • Adaptive reference — gdy goal się zmieni, MPC natychmiast adaptuje.

NMPC — Nonlinear MPC

Dla manipulatora Pandy model jest nieliniowy:

M(q)q¨+C(q,q˙)q˙+g(q)=τM(q) \ddot q + C(q, \dot q) \dot q + g(q) = \tau

Dyskretyzowane (np. RK4): xk+1=f(xk,uk)x_{k+1} = f(x_k, u_k) z ff nieliniowym. Problem MPC staje się NLP (Nonlinear Programming), rozwiązywany przez SQP (jak w TrajOpt, moduł 07) lub interior-point IPOPT.

Real-Time Iteration (RTI) — Diehl et al. 2002

Pełen NLP solver wymaga wielu zewnętrznych iteracji, każda z wewnętrzny QP. Za wolne dla 1 kHz. RTI: uruchamiaj tylko jedną iterację SQP per krok sterowania — QP jest liniaryzacją wokół poprzedniego rozwiązania. Sub-millisecond update rate.

Warm-starting: jako initial guess dla iteracji kk, weź rozwiązanie z iteracji k1k-1 shifted o 1 krok. Po shiftcie potrzeba tylko uzupełnić ostatni krok (typowo zerami).

Frameworki NMPC

  • ACADO (Houska, Ferreau, Diehl 2011) — code generation, embedded. Dziś przemianowane na acados.
  • do-mpc (Lucia, Tatulea-Codrean 2017) — Python wrapper wokół CasADi + IPOPT.
  • MPC-Tools — MATLAB.
  • OCS2 (ETH) — SLQ (sequential linear quadratic) dla legged robots.

iLQR / DDP — exploit struktury dynamicznej

NMPC traktuje problem jako gęsty NLP — nie wykorzystuje sequential charakteru (każdy stan zależy tylko od poprzedniego). DDP (Differential Dynamic Programming, Mayne 1966) i iLQR(Iterative LQR, Li & Todorov 2004) wykorzystują strukturę przez backward Riccati sweep:

  1. Forward pass: dla bieżącej trajektorii(xˉk,uˉk)(\bar x_k, \bar u_k), oblicz V(xk)V(x_k) w każdym kroku.
  2. Backward pass: Bellman backward — Vk(x)=minu((x,u)+Vk+1(f(x,u)))V_k(x) = \min_u (\ell(x,u) + V_{k+1}(f(x,u))). Aprokowane przez Taylor 2-go rzędu wokół (xˉ,uˉ)(\bar x, \bar u), daje feedback gains KkK_k i feedforward kkk_k.
  3. Update: uk=uˉk+kk+Kk(xkxˉk)u_k = \bar u_k + k_k + K_k (x_k - \bar x_k). Wykonaj forward pass, powtórz.

Złożoność: O(N(n3+m3))O(N (n^3 + m^3)) per iteracja vs O((Nm)3)O((Nm)^3) dla dense NLP. Dla N=100,n=14,m=7N = 100, n = 14, m = 7 (Panda) — DDP ~5 ms, dense IPOPT ~500 ms. Stąd DDP/iLQR dominują w real-time MPC manipulatorów.

iLQG (Iterative LQG) — DDP + stochastic noise. Crocoddyl (Mastalli et al. 2020) — najpopularniejsza biblioteka, używana w ANYmal, Cassie, dual-arm manipulation.

Demo: iLQR na 1D double-integratorze

Klasyczny pedagogiczny przykład: punkt materialny w 1D, stan xt=(pt,vt)x_t = (p_t, v_t), sterowanie ut=atu_t = a_t. Dynamika liniowa:

xt+1=Axt+But,A=[1Δt01],B=[12Δt2Δt]x_{t+1} = A x_t + B u_t,\quad A=\begin{bmatrix}1 & \Delta t\\ 0 & 1\end{bmatrix},\quad B=\begin{bmatrix}\tfrac{1}{2}\Delta t^2\\ \Delta t\end{bmatrix}

Koszt biegnący z nieliniowym członem barierowym:

c(x,u)=(ppgoal)2+wvv2+B0exp ⁣((ppb)2/σ2)+Ru2c(x,u) = (p-p_{\text{goal}})^2 + w_v v^2 + B_0\exp\!\big(-(p-p_b)^2/\sigma^2\big) + R u^2

Człon bump czyni koszt nieliniowym w pp — gdyby go nie było, iLQR zbiegłby w jednej iteracji (czyste LQR). Z bump-em każda iteracja liniaryzuje koszt wokół bieżącej trajektorii i daje inny zestaw gainsów KtK_t, ktk_t.

iLQR na 1D double-integratorze — backward Riccati sweep

p(t) — pozycja
-0.42.55.4pp_goal
v(t) — prędkość
-0.500.5
u(t) — sterowanie
-0.500.5
J vs iteracja (zbieżność)
581.571209.061836.55
Wynik backward Riccati sweep (iter 0)
Iteracja 0 = forward rollout z u=0 (brak backward sweep). Przesuń suwak iteracji ≥ 1 by zobaczyć K_t, V_xx_t.
kursor czasu:
Co obserwować: (1) ustaw bump = 0 — koszt liniowy, iLQR zbiega w jednej iteracji (LQR analityczny). (2) zwiększ bump — koszt nieliniowy w pp, iLQR potrzebuje kilku iteracji. (3) wykres KtK_t pokazuje feedback gain wzdłuż horyzontu — typowo wysoki na początku (długi czas na korekcję) i niższy pod koniec. (4) Vxx,tV_{xx,t} — drugi rząd cost-to-go, rośnie cofając się od końca horyzontu (akumulacja przyszłego kosztu). (5) krzywa JJ vs iteracja powinna być monotonicznie malejąca dzięki line-search α.

Co pokazuje wizualizacja

  • p(t), v(t), u(t) — trajektoria po wybranej iteracji. Iteracja 0 = forward rollout z u=0u=0 (pelna bezruchowa trajektoria).
  • K_t = [K_p, K_v] — feedback gain wzdłuż horyzontu, wynik backward sweep: Kt=Quu,t1Qux,tK_t = -Q_{uu,t}^{-1} Q_{ux,t}.
  • k_t — feedforward, też z backward sweep: kt=Quu,t1Qu,tk_t = -Q_{uu,t}^{-1} Q_{u,t}.
  • V_xx — cost-to-go drugiego rzędu, akumuluje się cofając od końca horyzontu (terminal: Vxx,N=2αfIV_{xx,N} = 2 \alpha_f I).
  • J vs iter— line-search z α < 1 gwarantuje monotoniczność.

Ćwiczenie: ustaw bump = 0 → konwergencja w 1 iteracji. Stopniowo rośnij bump → liczba iteracji rośnie, bo kwadratowa aproksymacja kosztu staje się coraz mniej dokładna. Skrajnie wysokie B0B_0 może spowodować odrzucenie kroku przez line-search.

MPPI — Sampling-Based MPC

Wszystkie powyższe wymagają różniczkowalnego modelu i kosztu. Co gdy mamy:

  • Symulator MuJoCo z kontaktem (nieróżniczkowalny przy impacts)?
  • Sieć neuronową jako model dynamiki?
  • Koszt z indicator function (zerojedynkowa kolizja)?

Rozwiązanie: MPPI (Model Predictive Path Integral, Williams et al. 2017) — gradient-free MPC oparty na sampling.

Per krok sterowania:

  1. Sample K perturbacji εkN(0,Σ)\varepsilon_k \sim \mathcal{N}(0, \Sigma) wzdłuż całego horyzontu.
  2. Wykonaj rollout dla każdego u+εku + \varepsilon_k, oblicz JkJ_k.
  3. Softmax weighting: wk=exp(Jk/λ)/Zw_k = \exp(-J_k / \lambda) / Z.
  4. Update nominalu: uu+kwkεku \leftarrow u + \sum_k w_k \varepsilon_k.
  5. Wykonaj u0u_0, shift trajectory, powtórz.

MPPI — step 0 / 40

best cost: 14.00 · ✓ reached
SG
K rollouts50
σ szumu0.60
λ temp0.30
Co zobaczyć: szare/zielone cienkie linie = K rolloutów ze szumem (zielony = niska koszt, ważone wyższą wagą). Fioletowa gruba linia = nominal control (mean ważony perturbacji). Niebieska gruba = faktyczna trajektoria wykonana. MPPI vs STOMP (moduł 07): obie używają weighted-rollouts, ale MPPI jest online closed-loop — w każdym kroku roluje K trajektorii, aplikuje tylko pierwszy control, shift'uje nominal o 1, dodaje zero na końcu (warm-start). Daje 50-100 Hz update rate na CPU.

Warianty MPPI

  • Tube-MPPI — łączy MPPI z tube MPC dla robustness przy stochastic dynamics.
  • Log-MPPI (Tao, Boots 2022) — log-likelihood weighting zamiast soft-max; lepsza zbieżność dla wąskich rozkładów.
  • Smooth MPPI — dodaje smoothing po update żeby uniknąć high-frequency chattering.
  • STORM (Bhardwaj et al. 2022) — STocastic Optimization for Reactive Motion. MPPI dla 7-DOF manipulatorów, ~50 Hz update na GPU.

MPPI vs CEM (Cross-Entropy Method): oba używają K rolloutów, ale CEM bierze top-N elite (np. 10%) i fits Gaussian do nich (zamiast soft-max). MPPI bardziej smooth update, CEM agresywniej fokusuje na najlepszych. Wybór: empiryczny.

CEM (Cross-Entropy Method) jako planer online

Per iteracja:

  1. Sample K control sequences from current Gaussian N(μ,Σ)\mathcal{N}(\mu, \Sigma).
  2. Rollout + oblicz koszt każdej.
  3. Wybierz top ρK\rho \cdot K najlepszych (typowo ρ=0.1\rho = 0.1).
  4. Fit Gaussian do top — nowe μ,Σ\mu, \Sigma.
  5. Iteruj kilka razy, weź μ\mu jako control.

CEM jest bardziej greedy niż MPPI (skupia się tylko na top), ale zbiega szybciej do lokalnego optimum. Standard w model-based RL — PETS (Chua 2018), PlaNet (Hafner 2019).

Real-time iteration i warm-starting

Wszystkie MPC mają wspólny problem: computational delay (czas między pomiarem a aplikacją). Dla 1 kHz update musi się wykonać < 1 ms.

Strategie:

  • RTI (Diehl 2002) — jedna iteracja SQP per krok, używaj liniaryzacji z poprzedniego.
  • Warm-start — początkowy guess = poprzednie rozwiązanie shifted o 1 krok.
  • Multiple shooting + sparse Jacobian — używaj struktury problemu (moduł 07).
  • Approximate solve — rozwiąż QP do tolerancji 10310^{-3} zamiast 10810^{-8}.
  • Code generation (FORCES Pro, acados) — specjalizowany kod C dla konkretnego problemu.
  • GPU parallelism — MPPI/CEM trivially parallel over K rolloutów.

Implementacje praktyczne

FrameworkTypTypowe zastosowanie
mujoco_mpciLQG + Predictive SamplingGoogle's MJPC — interactive MPC w MuJoCo Studio. Bezpośrednie demo dla manipulatorów (Panda, Allegro).
acadosNMPC z RTI + HPIPM solverEmbedded MPC dla autonomicznych pojazdów, dronów. Code generation w C.
CrocoddyliLQR / DDP / SQPManipulatory + legged robots. ANYmal, Cassie, dual-arm manipulation.
OCS2SLQ (Sequential LQ)Legged locomotion (ETH). ANYmal real-time MPC z constraintami.
TinyMPCLinear MPC, ADMMMicrocontroller-class MPC dla nano-drones (Cortex-M).
cuRobo (NVIDIA)MPPI + sampling-basedGPU MPC dla 7-DOF manipulatorów. K = 1000+ rolloutów per iteracja, 50+ Hz.
do-mpcNMPC (CasADi + IPOPT)Research / prototypy. Python frontend, łatwy do napisania.

Ściąga

Receding horizon pattern

  1. Zmierz stan x0x_0
  2. Rozwiąż optimization for next N steps: u=argminJ(x0,u0..N1)u^* = \arg\min J(x_0, u_{0..N-1})
  3. Zastosuj tylko u0u_0^*
  4. Powtórz

Linear MPC = QP

minu12uHu+gus.t.  Aub\min_u \tfrac{1}{2} u^\top H u + g^\top u \quad \text{s.t.} \; A u \leq b

MPPI update

uu+k=1Kwkεk,wk=eJk/λjeJj/λu \leftarrow u + \sum_{k=1}^K w_k \varepsilon_k, \quad w_k = \frac{e^{-J_k/\lambda}}{\sum_j e^{-J_j/\lambda}}

iLQR / DDP

Bellman backward pass z aprox. 2-go rzędu wokół trajektorii. Daje feedback gains KkK_k. O(Nn3)O(N \cdot n^3) per iteracja.

Wybór algorytmu

  • Linear, fast, no contact → Linear MPC + OSQP
  • Nonlinear, smooth, manipulator → iLQR / Crocoddyl
  • Non-diff cost, contact, sim-in-the-loop → MPPI / mujoco_mpc
  • GPU available, K=1000 rolloutów → cuRobo / STORM
  • Embedded MCU → TinyMPC / FORCES Pro

Referencje

  • Mayne, Rawlings, Rao & Scokaert, „Constrained model predictive control: Stability and optimality" (Automatica 2000) — fundament linear MPC + dowody stabilności.
  • Mayne, „A Second-Order Gradient Method for Determining Optimal Trajectories of Non-linear Discrete-Time Systems" (Int. J. Control 1966) — DDP origin.
  • Li & Todorov, „Iterative linear-quadratic regulator design for nonlinear biological movement systems" (ICINCO 2004) — iLQR.
  • Diehl, Bock, Schlöder, Findeisen, Nagy, Allgöwer, „Real-time optimization and nonlinear model predictive control of processes governed by differential-algebraic equations" (J. Process Control 2002) — RTI scheme.
  • Williams, Wagener, Goldfain, Drews, Rehg, Boots, Theodorou, „Information Theoretic MPC for Model-Based Reinforcement Learning" (ICRA 2017) — MPPI.
  • Bhardwaj, Sundaralingam, Mousavian, Chentanez, Fox, Birchfield, Boots, Ratliff, „STORM: An Integrated Framework for Fast Joint-Space Model-Predictive Control for Reactive Manipulation" (CoRL 2022).
  • Mastalli et al., „Crocoddyl: An Efficient and Versatile Framework for Multi-Contact Optimal Control" (ICRA 2020).
  • Verschueren et al., „acados — a modular open-source framework for fast embedded optimal control" (Math. Prog. Comp. 2021).
  • Howell, Gileadi, Tunyasuvunakool, Zakka, Erez, Tassa, „Predictive Sampling: Real-time Behaviour Synthesis with MuJoCo" (arXiv 2022) — mujoco_mpc.
  • Nguyen, Schwager, et al., „TinyMPC: Model-Predictive Control on Resource-Constrained Microcontrollers" (ICRA 2024).