Moduł 03 · numeryczne

Metody Jakobianowe

Jacobian Transpose, pseudoinwersja, Damped Least Squares, SDLS.

Dlaczego nie zamkniętą formułą?

Metoda analityczna (moduły 1–2) daje dokładne rozwiązanie i jest właściwym wyborem, gdy znamy zamkniętą formę dla danej geometrii, np. Puma 560 (forma A Piepera) czy UR5 (forma B). Schody zaczynają się gdy: (a) manipulator ma 7+ DOF, wtedy IK ma nieskończenie wiele rozwiązań i potrzeba dodatkowych kryteriów (Franka Panda, KUKA LBR iiwa); (b) używamy nietypowej geometrii bez gotowego wyprowadzenia, roboty chirurgiczne, prototypy, custom mechanizmy; (c) uczenie się dynamicznie zmienia model (np. estymacja online długości ogniw przy soft-robotach).

Dla typowych przemysłowych 6-DOF rozwiązanie zamknięte zawsze istnieje (Raghavan–Roth dowodzą, że dowolny 6-DOF ma co najwyżej 16 rzeczywistych rozwiązań i wszystkie da się wyznaczyć analitycznie), ale w praktyce jego wyprowadzenie bywa pracochłonne. Solvery numeryczne dają rozwiązanie „od ręki" dla dowolnej geometrii podanej tabelą DH, bez ręcznej algebry, bez zgadywania struktury wzorów. To czyni je domyślną opcją w prototypowaniu.

Potrzebujemy więc solverów numerycznych, działających dla dowolnego manipulatora, nawet jeśli równania są nieliniowe w sposób, który uniemożliwia ich odwrócenie ręcznie. Wszystkie metody tego modułu oparte są na jednym pomyśle: linearyzacji przez Jakobian.

Intuicja: metoda Newtona w jednym wymiarze

Zanim przejdziemy do przestrzeni konfiguracji 6-DOF, popatrzmy na analogiczny problem w 1D. Chcemy rozwiązać równanie f(x)=0f(x) = 0 dla pewnej gładkiej, nieliniowej funkcji ff. Bez zamkniętej formuły, używamy metody Newtona–Raphsona:

  1. Zgadujemy startową wartość x0x_0.
  2. Liczymy styczną do wykresu w punkcie (x0,f(x0))(x_0, f(x_0)).
  3. Przedłużamy styczną do przecięcia z osią X, nowe przybliżenie x1=x0f(x0)/f(x0)x_1 = x_0 - f(x_0)/f'(x_0).
  4. Powtarzamy: x2x_2 ze stycznej w x1x_1, i tak dalej.

Każda kolejna styczna „lepiej się dopasowuje" do miejsca zerowego xx^*. Po kilku iteracjach osiągamy dowolną precyzję:

xf(x)-2-112f(x) = x³ − 4x − 1x0x1x2x3 ≈ x*Iteracja Newtona:xₖ₊₁ = xₖ − f(xₖ) / f′(xₖ)styczna → przecięcie z osią x

Kluczowe spostrzeżenie: w jednym kroku nie próbujemy od razu trafić w rozwiązanie. Zamiast tego zastępujemy trudną, nieliniową funkcję ff jej łatwą, liniową aproksymacją (styczną) i rozwiązujemy problem liniowy, który umiemy. Dopiero powtarzanie tego schematu doprowadza nas do celu.

Czym właściwie jest Jakobian?

W 1D rolę „wrażliwości" wyjścia na wejście pełni pochodna f(x)f'(x). Mówi ona: „jeżeli zmienię xx o jednostkę, to y=f(x)y = f(x) zmieni się w przybliżeniu o f(x)f'(x) jednostek". W robotyce mamy wejście q=(q1,,qn)q = (q_1, \dots, q_n) (kąty przegubów) i wyjście ξ=(vx,vy,vz,ωx,ωy,ωz)\xi = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z) (prędkość liniowa i kątowa końcówki), sześć liczb wyjścia, n liczb wejścia. „Pochodna" takiego odwzorowania to macierz, właśnie Jakobian J(q)R6×nJ(q) \in \mathbb{R}^{6 \times n}:

J(q)  =  [vxq1vxqnωzq1ωzqn]J(q) \;=\; \begin{bmatrix} \dfrac{\partial v_x}{\partial q_1} & \cdots & \dfrac{\partial v_x}{\partial q_n} \\[2pt] \vdots & \ddots & \vdots \\[2pt] \dfrac{\partial \omega_z}{\partial q_1} & \cdots & \dfrac{\partial \omega_z}{\partial q_n} \end{bmatrix}

Wiersze macierzy odpowiadają sześciu składowym prędkości końcówki (3 translacyjne + 3 obrotowe). Kolumny macierzy odpowiadają poszczególnym przegubom, każda kolumna JiJ_i mówi, jak jednostkowa prędkość i-tego przegubu wpływa na końcówkę:

„Jeśli obrócę przegub qᵢ o maleńki kąt,w którą stronę pojedzie końcówka?"q₁q₂końcówka (TCP)J₁ · q̇₁J₂ · q̇₂strzałki = chwilowy kierunek ruchu końcówkiprzy obrocie TYLKO tego przegubuKażda kolumna jakobianu =wkład jednego przegubudo ruchu końcówki.Kolumna J₁:prędkość końcówki,gdy q̇₁ = 1, reszta = 0Kolumna J₂:prędkość końcówki,gdy q̇₂ = 1, reszta = 0Suma wkładów:ξ = J₁q̇₁ + J₂q̇₂ = J(q) · q̇

Innymi słowy: wyobraź sobie, że obracasz tylko jeden przegub, resztę trzymasz nieruchomo. Końcówka zakreśla łuk, lokalnie wektor jej prędkości to właśnie kolumna Jakobianu odpowiadająca temu przegubowi. Jeśli wszystkie przeguby obracają się jednocześnie, ich wkłady się dodają liniowo (bo różniczkowanie jest liniowe):

ξ  =  J1(q)q˙1+J2(q)q˙2++Jn(q)q˙n  =  J(q)q˙\xi \;=\; J_1(q)\,\dot q_1 + J_2(q)\,\dot q_2 + \cdots + J_n(q)\,\dot q_n \;=\; J(q)\,\dot q

Trzy kluczowe rzeczy do zapamiętania o Jakobianie:

  1. Jakobian zależy od qq. To nie jest „stała macierz robota", to pochodna cząstkowa w konkretnym punkcie. Gdy zmieniasz konfigurację, Jakobian się zmienia. Stąd w pętli iteracyjnej musimy go przeliczać za każdym razem.
  2. Jakobian łączy prędkości, nie pozycje. Relacja ξ=Jq˙\xi = J\dot q jest między prędkością końcówki a prędkościami przegubów. Dla małych przyrostów (lokalnie) mamy ΔxJΔq\Delta x \approx J \, \Delta q, stąd iteracyjne rozwiązanie IK.
  3. Dla przegubów obrotowych istnieje jawny wzór. Nie trzeba różniczkować symbolicznie, kolumnę JiJ_i można zapisać geometrycznie (zobacz StepPanel 1 niżej): wkład do prędkości liniowej końcówki to z^i×(peepi)\hat{\mathbf{z}}_i \times (\mathbf{p}_\text{ee} - \mathbf{p}_i) (iloczyn wektorowy osi obrotu z wektorem „promień od osi do końcówki"); wkład do prędkości kątowej, to sama oś z^i\hat{\mathbf{z}}_i. Dla przegubu przesuwnego jest jeszcze prościej: tylko wkład liniowy z^i\hat{\mathbf{z}}_i, zero wkładu kątowego.

Newton w 6 wymiarach, powrót do IK

Teraz łączymy obie intuicje. W IK rozwiązujemy F(q)=0\mathbf{F}(q) = \mathbf{0}, gdzie F(q)=Tf(q)\mathbf{F}(q) = T^{*} \ominus f(q) jest wektorowym błędem pozy (6-wymiarowym, translacja + rotacja). W metodzie Newtona rolę „dzielenia przez pochodną" (z 1D) pełni pseudoinwersja Jakobianu JJ^\dagger:

xk+1=xkf(xk)f(xk)1D Newtonqk+1=qk+J(qk)e(qk)6D Newton dla IK\underbrace{x_{k+1} = x_k - \frac{f(x_k)}{f'(x_k)}}_{\text{1D Newton}} \quad\longrightarrow\quad \underbrace{q_{k+1} = q_k + J^{\dagger}(q_k)\,\mathbf{e}(q_k)}_{\text{6D Newton dla IK}}

(znak się odwraca, bo definiujemy błąd jako e=Tf(q)\mathbf{e} = T^* \ominus f(q), nie f(q)Tf(q) - T^*, ale struktura kroku jest identyczna). Resztę wariantów, Jacobian Transpose, DLS, Adaptive DLS, zobaczymy niżej jako modyfikacje tego samego kroku, różnie radzące sobie z trudnościami, gdy Jakobian jest źle uwarunkowany.

Anatomia pojedynczej iteracji

Pojedyncza iteracja solvera Jakobianowego to pięć etapów wykonywanych w stałej kolejności. Po piątym sprawdzamy warunek stopu i albo kończymy, albo wracamy do pierwszego z nową wartością qq:

1. FK aktualnej konfiguracjiTₖ = f(qₖ)2. Oblicz błąd pozy (twist)eₖ = log(T* · Tₖ⁻¹) ∈ ℝ⁶3. Oblicz jakobian J(qₖ)macierz 6×n, zależna od qₖ4. Wyznacz krok Δqₖ (zależnie od wariantu)α · Jᵀ · e , transposeJ† · e , pseudoinverseJᵀ(JJᵀ + λ²I)⁻¹ · e , DLS5. Aktualizuj konfiguracjęqₖ₊₁ = qₖ + Δqₖ‖eₖ‖ < ε?warunek stoputakq* = qₖk ← k+1startq₀ = seed

Zauważ: JJ liczymy od nowa w każdej iteracji, bo zależy od aktualnego qkq_k. To nie jest „statyczna macierz robota"; to pochodna cząstkowa wyliczana w bieżącym punkcie przestrzeni konfiguracji. Gdyby FK była liniowa, wystarczyłaby jedna iteracja (tak jak Newton na funkcji liniowej trafia w zero od razu). FK jest silnie nieliniowe, stąd konieczność pętli.

Pseudokod

q ← q_seed              // zgadnięta/znana konfiguracja startowa
for k = 0, 1, 2, … do
    T_k ← FK(q)                            // 1. FK
    e_k ← twist_error(T_k, T_target)       // 2. błąd w SE(3)
    if  ‖e_k‖  <  ε  then  return  q       //    warunek stopu
    J_k ← jacobian(q)                      // 3. jakobian w aktualnym punkcie
    Δq  ← solve_step(J_k, e_k, method)     // 4. krok (Transpose / Pinv / DLS / SDLS)
    q   ← q + α · Δq                       // 5. aktualizacja (α = step size)
end for
return  q  // osiągnięto limit iteracji bez zbieżności

Klucz do zrozumienia, dwa poziomy „nieliniowości"

  • Zewnętrzna pętla po iteracjach, to ta, która pozwala nam pokonać nieliniowość FK. Po każdym kroku linearyzujemy od nowa w nowym punkcie qkq_k.
  • Wewnętrzny krok liniowy, rozwiązujemy układ JΔq=eJ\,\Delta q = e. To jest łatwe (algebra liniowa), ale wrażliwe: przy złym uwarunkowaniu JJ krok staje się ogromny, a wtedy punkt qk+1q_{k+1} wylatuje poza obszar, w którym linearyzacja obowiązywała. Stąd modyfikacje, tłumienie, ograniczanie kroku, które poznamy dalej.

Co oznacza „zbieżność" i kiedy jej brak

Zbieżność to spadek normy błędu ek\|\mathbf{e}_k\| do zera. W dobrym przypadku spadek jest kwadratowy (przy pełnym Newtonie i pseudoinwersji w okolicy rozwiązania): błąd w iteracji k+1k+1 jest proporcjonalny do kwadratu błędu w iteracji kk. Oznacza to, że liczba cyfr dokładnych się podwaja z każdym krokiem.

Co może pójść nie tak:

  • Rozbieżność, gdy krok Δq\Delta q jest za duży (np. w pobliżu singularności JJ źle uwarunkowana), qk+1q_{k+1} skacze do obszaru, gdzie linearyzacja już nie ma sensu. Kolejne iteracje pogłębiają problem. Ratunek: tłumienie (DLS) albo line-search.
  • Oscylacje, solver oscyluje w okolicy rozwiązania zamiast w nie wchodzić. Typowe dla Jacobian Transpose ze zbyt dużym α\alpha albo dla metod bez adaptacyjnego kroku.
  • Stagnacja, krok staje się mikroskopijny (np. Je0J^\top \mathbf{e} \approx 0 gdy Transpose trafi w lokalny pseudominimalny punkt). Solver „utyka" bez osiągnięcia tolerancji.
  • Zbieg do innej gałęzi, dla Pumy mamy 8 rozwiązań; iteracyjny solver przyciąga się do tego, które jest najbliższe seedowi. Zmiana seeda może dać inną gałąź. To nie jest błąd, to cecha metody.

W panelu „Porównanie na żywo" niżej zobaczysz te zjawiska w praktyce: Transpose często stagnuje (potrzebuje tysięcy iteracji), Pseudoinwersja bywa niestabilna przy singularnościach, DLS jest niezawodny ale z residualnym błędem, Adaptive DLS łączy zalety obydwu.

Krok 1

Jakobian geometryczny, definicja

Niech f:QSE(3)f: Q \to SE(3) będzie FK. Różniczka Frécheta dfq:TqQTf(q)SE(3)se(3)=R6df_q: T_q Q \to T_{f(q)} SE(3) \cong \mathfrak{se}(3) = \mathbb{R}^6 zapisana w bazie standardowej daje macierz 6×n zwaną jakobianem geometrycznym:

J(q)  =  [J1(q)    J2(q)        Jn(q)]R6×nJ(q) \;=\; \bigl[\,J_1(q)\;|\;J_2(q)\;|\;\cdots\;|\;J_n(q)\,\bigr] \in \mathbb{R}^{6 \times n}

Dla przegubu obrotowego i kolumna ma postać:

Ji(q)  =  [z^i×(peepi)z^i]J_i(q) \;=\; \begin{bmatrix} \hat{z}_i \times (\mathbf{p}_{\text{ee}} - \mathbf{p}_i) \\ \hat{z}_i \end{bmatrix}

gdzie z^i\hat{z}_i jest jednostkowym wektorem osi obrotu przegubu i w ramce bazowej, a pi\mathbf{p}_i, dowolnym punktem na tej osi (w implementacji: początek układu współrzędnych i-tej). Dla przegubu przesuwnego:Ji=[z^i;  0]J_i = [\hat{z}_i;\; \mathbf{0}].

Sens fizyczny: JiJ_i to wkład jednostkowej prędkości q˙i\dot q_i do wektora prędkości przestrzennej efektora ξ=[v;ω]\xi = [\mathbf{v};\, \boldsymbol{\omega}]^\top, a całościowo:

ξ=J(q)q˙\xi = J(q)\,\dot q

Nieliniowy problem IK staje się lokalnie liniowy:

e(q)J(q)ΔqΔq=J(q)e(q)\mathbf{e}(q) \approx J(q)\,\Delta q \quad \Rightarrow \quad \Delta q = J^{\dagger}(q)\,\mathbf{e}(q)

gdzie e(q)\mathbf{e}(q) to twist error:

e(q)=[pp(q)log ⁣(RR(q))]\mathbf{e}(q) = \begin{bmatrix} \mathbf{p}^* - \mathbf{p}(q) \\ \log\!\bigl(R^*\,R(q)^\top\bigr) \end{bmatrix}

Część obrotowa to logarytm SO(3), wektorω=θk^\boldsymbol{\omega} = \theta\,\hat{k} reprezentujący obrót, który trzeba wykonać, by przejść z aktualnej orientacji do zadanej. Dla małych obrotów pokrywa się to z różnicą kątów Eulera, ale w ogólnym przypadku wymaga świadomej ekstrakcji osi i kąta z RSO(3)R \in SO(3).

Krok 2

Metoda I, Jacobian Transpose

Najprostsza iteracja: zamiast odwracać JJ, użyj jego transpozycji jako przybliżenia pseudoinwersji (kierunek ten sam, skala nieodpowiednia):

Δq=αJe\Delta q = \alpha\,J^{\top}\,\mathbf{e}

Metoda jest w istocie gradientem zstępowania na 12e2\tfrac{1}{2}\|\mathbf{e}\|^2, pochodna względem qq to Je-J^\top \mathbf{e}. Optymalny krok (wzdłuż Jᵀe minimalizujący błąd liniowy) znajduje się z:

α=e,  JJeJJe2\alpha^* = \frac{\langle \mathbf{e},\; J J^\top \mathbf{e}\rangle}{\|J J^\top \mathbf{e}\|^2}

Zalety: nie wymaga rozwiązywania układu liniowego (tylko macierz-wektor), jest odporny na singularności (Jᵀ nigdy nie "wybucha"). Wady: zbieżność liniowa, setki–tysiące iteracji dla średnich pozycji docelowych.

const JtE  = matvec(Jᵀ, e);
const JJtE = matvec(J, JtE);
const α    = (e·JJtE) / (JJtE·JJtE);
Δq = JtE.map(v => α * v);
Krok 3

Metoda II, Pseudoinwersja Moore–Penrose

Bezpośrednie odwrócenie liniowego modelu. Dla n6n \geq 6 (kwadratowego lub nadokreślonego) prawostronna inwersja minimalizująca Δq\|\Delta q\|:

J=J(JJ)1,Δq=JeJ^{\dagger} = J^{\top}\,(J\,J^{\top})^{-1}, \qquad \Delta q = J^{\dagger}\,\mathbf{e}

Implementacyjnie: rozwiązujemy JJy=eJ J^\top y = \mathbf{e} (układ 6×6), a potem Δq=Jy\Delta q = J^\top y.

Problem singularności: gdy det(JJ)0\det(J J^\top) \to 0 (np. q50q_5 \to 0 dla nadgarstka sferycznego), (JJ)1(J J^\top)^{-1} ma bardzo duże wartości własne. Krok Δq\Delta q staje się ogromny → linearyzacja jest nieważna → solver rozbiega się lub „skacze" przez singularność.

Dla 7-DOF i innych manipulatorów redundantnych (n>6n > 6) wariant right pseudoinverse pozostawia przestrzeń zerową jakobianu (ang. null-space) N(J)\mathcal{N}(J) nietrywialną, czyli istnieją niezerowe zmiany kątów przegubów, które nie zmieniają pozy efektora. Można je wykorzystać do spełnienia dodatkowych ograniczeń (kolizje, limity przegubowe). Temat rozwiniemy w module 7.

Krok 4

Metoda III, Damped Least Squares (Levenberg–Marquardt)

Kompromis między pseudoinwersją (szybka, niestabilna) a transpozycją (powolna, stabilna): dodaj tłumienie λ2I\lambda^2 I do macierzy, którą odwracasz:

Δq=J(JJ+λ2I)1e\Delta q = J^{\top}\,(J J^\top + \lambda^2 I)^{-1}\,\mathbf{e}

Równoważnie Δq\Delta q minimalizuje funkcjonał:

Δq=argminΔq  eJΔq2+λ2Δq2\Delta q = \arg\min_{\Delta q}\;\|\mathbf{e} - J\,\Delta q\|^2 + \lambda^2\,\|\Delta q\|^2

To klasyczne tłumienie Tichonowa: λ\lambda jest kosztem za każde jednostkowe przemieszczenie Δq\Delta q. Macierz JJ+λ2IJ J^\top + \lambda^2 I jest zawsze dodatnio określona (nawet przy pełnej singularności JJ), więc solver pozostaje stabilny. Kosztem jest błąd residualny λ\sim \lambda, idealnie zerowa zbieżność wymaga λ0\lambda \to 0, co przywraca problemy pseudoinwersji.

Levenberg i Marquardt zaproponowali tę formę w kontekście nieliniowego najmniejszych kwadratów; dla IK jest to de facto standard przemysłowy (używany m.in. w ROS MoveIt jakoKDL Inverse Kinematics).

Krok 5

Metoda IV, Adaptive DLS (tłumienie zależne od residuum)

Słabość stałego λ\lambda: za małe ⇒ problemy w singularności; za duże ⇒ wolna zbieżność daleko od celu. Praktyczna heurystyka (Levenberg-Marquardt-style):

λeff(e)=max ⁣(λ0,  ce)\lambda_{\text{eff}}(\mathbf{e}) = \max\!\bigl(\lambda_0,\; c\,\|\mathbf{e}\|\bigr)

Daleko od celu (e\|\mathbf{e}\| duże), λeff\lambda_{\text{eff}} duże, krok ostrożny. Blisko celu,λeffλ0\lambda_{\text{eff}} \to \lambda_0, zbieżność tight. Wariant dodatkowy: kap wielkości kroku per-przegub (tu 0,3 rad), zapobiega „przeskokom" przy dużej linearyzacji.

Buss–Kim (2005) Selectively DLS: prawdziwy SDLS używa SVD J=UΣVJ = U\Sigma V^\top i tłumi każdy kierunek osobno zależnie od σi\sigma_i. Dla celów dydaktycznych pokazujemy powyższy uproszczony wariant, który ma ten sam efekt ilościowy bez kosztu SVD.

Porównanie na żywo

Cztery solvery startują z tego samego seeda (konfiguracja głównego kontrolera) i zmierzają do tej samej pozy docelowej TT^*. Zobaczysz to, co odróżnia dobry solver od „papierowego": liczbę iteracji, czas i, krytyczne, stabilność przy trudnych celach (spróbuj pozy bliskiej wyciągnięcia ramienia lub wyrównania osi nadgarstka).

Konfiguracja przegubów

θ₁2.8°
θ₂-77.7°
θ₃6.8°
θ₄8.5°
θ₅-19.3°
θ₆172.0°

Poza efektora (T₀⁶)

Pozycja [m]
x = 0.5000
y = 0.1500
z = 0.3000
Orientacja RPY [°]
R = 0.00
P = 90.00
Y = 0.00

Poza docelowa T*

Pozycja [m]
Orientacja RPY [°]

Parametry porównania

1e-81e-71e-61e-51e-41e-31e-21e-11e+0000111iteracje‖Δp‖ [m]
1e-81e-71e-61e-51e-41e-31e-21e-11e+0000111iteracjeΔR [rad]
metodaiteracje‖Δp‖ końcowe [m]ΔR końcowe [rad]czas [ms]status

Trajektorie końcówki w trakcie iteracji

Każdy z czterech solverów startuje z tego samego seeda (aktualna konfiguracja głównego kontrolera) i zmierza do tej samej pozy docelowej (czerwona kropka). Pełna linia pokazuje ścieżkę TCP po kolejnych iteracjach, widać wprost, jak szybko solver dochodzi do celu i jaką drogą (prosta, kręta, oscylująca).

Syntetyczne porównanie

AspektTransposePinvDLSAdapt. DLS
Koszt iteracjiO(n²)O(n³)O(n³)O(n³)
Liczba iteracji~10³~10~10²~10²
Singularnościodpornyrozbiega sięodporny (z błędem ~λ)odporny + precyzyjny
Implementacjatrywialnaprostaprostaz heurystyką
W praktyce używany?rzadkotak, z zabezpieczeniamitak, standardtak, RMS, MoveIt

Co dalej

W module 4 sformułujemy IK jako problem optymalizacji z ograniczeniami (ograniczenia przegubowe, unikanie kolizji, multi-cel) i zastosujemy solvery globalne (Nelder–Mead, SQP, ewolucyjne). W module 7 wrócimy do tematu manipulacyjności i pokażemy, jak analiza SVD Jakobianu daje operatywną miarę odległości od singularności, i jak można ją włączyć jako dodatkowy cel optymalizacyjny w przestrzeni zerowej jakobianu.

Powiązania z dynamiką: Jakobian w tym module mapuje q̇ → ẋ (pierwsza pochodna). Druga pochodna i siły potrzebne do wytworzenia ruchu to temat modułu 9 (Newton-Euler): ten sam łańcuch propagacji od bazy do efektora, ale z prędkościami, przyspieszeniami i siłami w każdym ogniwie.