Jacobian Transpose, pseudoinwersja, Damped Least Squares, SDLS.
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.
Zanim przejdziemy do przestrzeni konfiguracji 6-DOF, popatrzmy na analogiczny problem w 1D. Chcemy rozwiązać równanie dla pewnej gładkiej, nieliniowej funkcji . Bez zamkniętej formuły, używamy metody Newtona–Raphsona:
Każda kolejna styczna „lepiej się dopasowuje" do miejsca zerowego . Po kilku iteracjach osiągamy dowolną precyzję:
Kluczowe spostrzeżenie: w jednym kroku nie próbujemy od razu trafić w rozwiązanie. Zamiast tego zastępujemy trudną, nieliniową funkcję jej łatwą, liniową aproksymacją (styczną) i rozwiązujemy problem liniowy, który umiemy. Dopiero powtarzanie tego schematu doprowadza nas do celu.
W 1D rolę „wrażliwości" wyjścia na wejście pełni pochodna . Mówi ona: „jeżeli zmienię o jednostkę, to zmieni się w przybliżeniu o jednostek". W robotyce mamy wejście (kąty przegubów) i wyjście (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 :
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 mówi, jak jednostkowa prędkość i-tego przegubu wpływa na końcówkę:
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):
Trzy kluczowe rzeczy do zapamiętania o Jakobianie:
Teraz łączymy obie intuicje. W IK rozwiązujemy , gdzie jest wektorowym błędem pozy (6-wymiarowym, translacja + rotacja). W metodzie Newtona rolę „dzielenia przez pochodną" (z 1D) pełni pseudoinwersja Jakobianu :
(znak się odwraca, bo definiujemy błąd jako , nie , 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.
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ą :
Zauważ: liczymy od nowa w każdej iteracji, bo zależy od aktualnego . 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.
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ściZbieżność to spadek normy błędu do zera. W dobrym przypadku spadek jest kwadratowy (przy pełnym Newtonie i pseudoinwersji w okolicy rozwiązania): błąd w iteracji jest proporcjonalny do kwadratu błędu w iteracji . Oznacza to, że liczba cyfr dokładnych się podwaja z każdym krokiem.
Co może pójść nie tak:
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.
Niech będzie FK. Różniczka Frécheta zapisana w bazie standardowej daje macierz 6×n zwaną jakobianem geometrycznym:
Dla przegubu obrotowego i kolumna ma postać:
gdzie jest jednostkowym wektorem osi obrotu przegubu i w ramce bazowej, a , dowolnym punktem na tej osi (w implementacji: początek układu współrzędnych i-tej). Dla przegubu przesuwnego:.
Sens fizyczny: to wkład jednostkowej prędkości do wektora prędkości przestrzennej efektora , a całościowo:
Nieliniowy problem IK staje się lokalnie liniowy:
gdzie to twist error:
Część obrotowa to logarytm SO(3), wektor 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 .
Najprostsza iteracja: zamiast odwracać , użyj jego transpozycji jako przybliżenia pseudoinwersji (kierunek ten sam, skala nieodpowiednia):
Metoda jest w istocie gradientem zstępowania na , pochodna względem to . Optymalny krok (wzdłuż Jᵀe minimalizujący błąd liniowy) znajduje się z:
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);Bezpośrednie odwrócenie liniowego modelu. Dla (kwadratowego lub nadokreślonego) prawostronna inwersja minimalizująca :
Implementacyjnie: rozwiązujemy (układ 6×6), a potem .
Problem singularności: gdy (np. dla nadgarstka sferycznego), ma bardzo duże wartości własne. Krok staje się ogromny → linearyzacja jest nieważna → solver rozbiega się lub „skacze" przez singularność.
Dla 7-DOF i innych manipulatorów redundantnych () wariant right pseudoinverse pozostawia przestrzeń zerową jakobianu (ang. null-space) 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.
Kompromis między pseudoinwersją (szybka, niestabilna) a transpozycją (powolna, stabilna): dodaj tłumienie do macierzy, którą odwracasz:
Równoważnie minimalizuje funkcjonał:
To klasyczne tłumienie Tichonowa: jest kosztem za każde jednostkowe przemieszczenie . Macierz jest zawsze dodatnio określona (nawet przy pełnej singularności ), więc solver pozostaje stabilny. Kosztem jest błąd residualny , idealnie zerowa zbieżność wymaga , 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).
Słabość stałego : za małe ⇒ problemy w singularności; za duże ⇒ wolna zbieżność daleko od celu. Praktyczna heurystyka (Levenberg-Marquardt-style):
Daleko od celu ( duże), duże, krok ostrożny. Blisko celu,, 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 i tłumi każdy kierunek osobno zależnie od . Dla celów dydaktycznych pokazujemy powyższy uproszczony wariant, który ma ten sam efekt ilościowy bez kosztu SVD.
Cztery solvery startują z tego samego seeda (konfiguracja głównego kontrolera) i zmierzają do tej samej pozy docelowej . 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).
| metoda | iteracje | ‖Δp‖ końcowe [m] | ΔR końcowe [rad] | czas [ms] | status |
|---|
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).
| Aspekt | Transpose | Pinv | DLS | Adapt. DLS |
|---|---|---|---|---|
| Koszt iteracji | O(n²) | O(n³) | O(n³) | O(n³) |
| Liczba iteracji | ~10³ | ~10 | ~10² | ~10² |
| Singularności | odporny | rozbiega się | odporny (z błędem ~λ) | odporny + precyzyjny |
| Implementacja | trywialna | prosta | prosta | z heurystyką |
| W praktyce używany? | rzadko | tak, z zabezpieczeniami | tak, standard | tak, RMS, MoveIt |
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.