Moduł 08 · bonus

Reprezentacje orientacji

Macierz rotacji, kąty Eulera, axis-angle, wektor rotacji, kwaterniony, konwersje, gimbal lock, kiedy czego używać.

Po co tyle reprezentacji?

Pozycja w 3D to wektor, trzy liczby, koniec. Z orientacją jest inaczej: jedna i ta sama orientacja może być zapisana co najmniej na pięć różnych sposobów, każdy z innymi zaletami i wadami. Brak „uniwersalnego" zapisu, który byłby najlepszy do wszystkiego, używamy różnych w różnych sytuacjach:

  • Macierz rotacji, bezpośrednio mnożymy w obliczeniach geometrycznych (FK, transformacje punktów).
  • Kąty Eulera (RPY), wpisuje człowiek w panel sterowania, łatwe do interpretacji wzrokowej.
  • Axis-angle / wektor rotacji, wzrokowo intuicyjne („obróć o 90° wokół osi pionowej"), używane np. w OpenCV.
  • Kwaterniony, interpolacja, składanie wielu rotacji, brak singularności, standard w grafice i niskopoziomowym sterowaniu.

Każda z tych reprezentacji opisuje element grupy SO(3)SO(3), zbioru obrotów w 3D. Sama grupa to obiekt 3-wymiarowy (3 stopnie swobody), ale różne sposoby jej sparametryzowania używają różnej liczby liczb (3, 4 lub 9) z różnymi ograniczeniami.

Cel tego modułu: zrozumieć każdą z reprezentacji na poziomie intuicyjnym i obliczeniowym, znać pułapki (gimbal lock!), umieć sprawnie konwertować między nimi i wybrać właściwą do zadania.

Interaktywny eksplorator

Trzy slidery RPY definiują tę samą orientację w 3D. Po prawej zobacz ją zapisaną w pięciu reprezentacjach jednocześnie. Manipuluj suwakami i obserwuj, które liczby się zmieniają i jak (kwaterniony chodzą gładko zawsze; kąty Eulera mają nieciągłości przy pitch = ±90°; macierz zawsze ortogonalna).

Sterowanie orientacją (RPY w stopniach)

Roll (X)30.0°
Pitch (Y)45.0°
Yaw (Z)60.0°
1. Macierz rotacji R ∈ SO(3)
  0.3536  -0.5732   0.7392
  0.6124   0.7392   0.2803
 -0.7071   0.3536   0.6124
9 liczb, 6 ograniczeń (ortonormalność kolumn) → 3 stopnie swobody.
2. Kąty Eulera RPY (Z·Y·X)
roll = 30.00° (0.5236 rad)
pitch = 45.00° (0.7854 rad)
yaw = 60.00° (1.0472 rad)
3 liczby, minimalna parametryzacja. Singularność przy pitch = ±90°.
3. Axis-angle (oś, kąt)
k̂ = (0.0391, 0.7728, 0.6335)
θ = 69.36° (1.2105 rad)
4 liczby (oś jednostkowa: 3 + 1 ograniczenie + kąt: 1) → 3 DOF.
4. Wektor rotacji r = θ·k̂
r = (0.0474, 0.9354, 0.7668)
3 liczby. ‖r‖ = θ, kierunek r = oś. Używane w OpenCV i ROS.
5. Kwaternion jednostkowy
w = 0.8224
x = 0.0223
y = 0.4397
z = 0.3604
‖q‖ = 1.000000
4 liczby z 1 ograniczeniem (‖q‖ = 1). Brak singularności. q i −q to ten sam obrót.
Krok 1

Macierz rotacji R ∈ SO(3), fundament

Najbardziej bezpośrednia reprezentacja: macierz 3×33 \times 3, której kolumny to obrazy bazowych wektorów osi po rotacji:

R=[Rx^Ry^Rz^]R = \begin{bmatrix} R\hat{\mathbf{x}} & R\hat{\mathbf{y}} & R\hat{\mathbf{z}} \end{bmatrix}

Cechy: 9 liczb, ale z 6 ograniczeniami:

  • Ortonormalność kolumn, każda kolumna jest wektorem jednostkowym (3 ograniczenia).
  • Wzajemna ortogonalność, każda para kolumn jest prostopadła (3 ograniczenia).
  • Razem: 9 − 6 = 3 stopnie swobody, tyle, ile potrzeba.
  • det(R) = +1, wykluczamy odbicia (te miałyby det = −1).

Algebraicznie: RR=IR^\top R = I oraz detR=+1\det R = +1. Inwersja jest banalnie tania:

R1=RR^{-1} = R^{\top}

Zalety: kompozycja rotacji = zwykłe mnożenie macierzowe (R12=R1R2R_{12} = R_1 \cdot R_2). Transformacja wektora, zwykłe v=Rv\mathbf{v}' = R\mathbf{v}. Forma używana w 99% wzorów kinematyki (FK, jakobian, równania DH).

Wady:

  • Redundantna (9 liczb dla 3 DOF), po długich ciągach mnożeń narastają błędy zmiennoprzecinkowe i macierz przestaje być ściśle ortogonalna. Trzeba okresowo reortonormalizować (np. SVD lub Gram-Schmidt).
  • Niewygodna do interpolacji („średnia" dwóch macierzy nie jest macierzą rotacji).
  • Mało intuicyjna dla człowieka, patrząc na 9 liczb trudno powiedzieć, jaki to obrót.
Krok 2

Kąty Eulera (RPY), minimum, ale z gimbal lock

Reprezentujemy rotację jako kompozycję trzech obrotów wokół osi. Najczęściej używane w robotyce: roll, pitch, yaw (przechylenie, pochylenie, odchylenie), kolejność osi ZYX intrinsic:

R=Rz(yaw)Ry(pitch)Rx(roll)R = R_z(\text{yaw}) \cdot R_y(\text{pitch}) \cdot R_x(\text{roll})

Słownie: najpierw obracamy wokół osi X (roll), potem wokół nowej osi Y (pitch), na końcu wokół najnowszej osi Z (yaw). Jeśli czytasz macierze od prawej do lewej, to jest właśnie ta kolejność.

Zalety: tylko 3 liczby (minimalna parametryzacja). Łatwo wpisać w panel, łatwo zinterpretować geometrycznie. Standardowy sposób komunikacji człowiek-robot.

Wady, patologie:

  • Gimbal lock, przy pitch = ±90° tracimy stopień swobody. Roll i yaw stają się nierozróżnialne (zmiana jednego daje to samo co zmiana drugiego). To nie jest błąd implementacji, to nieusuwalna konsekwencja parametryzacji.
  • Niejednoznaczność, ta sama orientacja może być zapisana wieloma trójkami liczb (np. (0°, 90°, 30°) ≡ (30°, 90°, 0°)).
  • Nieciągłość interpolacji, interpolacja liniowa kątów daje paskudne efekty wizualne (skoki przy ±180°).
  • Plątanina konwencji, patrz niżej.

Konwencje kątów Eulera

„Kąty Eulera" to nie jeden zapis, to cała rodzina. Różnią się kolejnością osi (XYZ, ZYX, ZYZ, ZXZ, …) i tym, czy obroty są intrinsic (wokół osi obracanego ciała) czy extrinsic (wokół osi nieruchomego świata):

12 różnych „kątów Eulera" (× 2 dla intrinsic vs extrinsic = 24 konwencje)Te same trzy liczby (np. 30°, 45°, 60°) dają RÓŻNE rotacje w różnych konwencjachRoll-Pitch-Yaw (RPY)ZYX intrinsicRobotyka, lotnictwo, ROSTait-Bryan XYZXYZ intrinsicGrafika 3D, UnityEulera ZYZZYZ intrinsicMechanika klasycznaEulera ZXZZXZ intrinsicAstronomia, mechanika ciał sztywnychNie istnieje „prawidłowa" konwencja, istnieje konwencja, którą używasz w swoim systemie.

Praktyczna porada: zawsze dokumentuj, którą konwencję używasz. „RPY" w robotyce zwykle oznacza ZYX intrinsic (ROS, MoveIt, OpenRAVE), ale w lotnictwie i grafice 3D bywa różnie. Konwersja źle dopasowanych konwencji to klasyczne źródło bugów w integracji z czujnikami i bibliotekami zewnętrznymi.

Krok 3

Gimbal lock, ilustracja na żywo

Każda rotacja w 3 wymiarach to złożenie obrotów wokół trzech osi. Wyobraź sobie żyroskop z trzema obręczami, każda umożliwia obrót wokół innej osi, połączone w łańcuch. Gimbal lock zachodzi, gdy dwie z tych osi się pokrywają:

Trzy obręcze gimbala

Yaw (Z)0.0°
Pitch (Y)70.0°
Roll (X)20.0°

Spróbuj: ustaw pitch ≈ 90°. Czerwona (yaw) i niebieska (roll) obręcze zaczynają obracać się wokół tej samej osi, tracisz jeden stopień swobody. Zmiana yaw daje teraz to samo co zmiana roll. To jest gimbal lock, nieusuwalna patologia kątów Eulera.

Gimbal lock w fizycznym żyroskopie utrudnia pracę pilotom (znany problem w Apollo 11), a w robotyce destabilizuje regulatory posługujące się kątami Eulera w okolicach pitch ≈ ±90°. Rozwiązanie: używać kwaternionów lub macierzy rotacji jako reprezentacji wewnętrznej (kąty Eulera tylko do wejścia/wyjścia interfejsu użytkownika).

Krok 4

Axis-angle (oś-kąt) i wektor rotacji

Twierdzenie Eulera o obrotach: każdy obrót w 3D można opisać jako jeden obrót o pewien kąt θ wokół jednej osi k̂. To jest fakt geometryczny, stosuje się również do złożenia 100 wcześniejszych obrotów.

Kierunek rotacjiwokół osi określamy regułą prawej ręki: jeśli kciuk wskazuje wzdłuż osi k̂, palce wskazują kierunek obrotu dla θ > 0. Ta sama konwencja definiuje orientację układu współrzędnych prawoskrętnego (X×Y = Z):

Reguła prawej ręki dla kartezjańskich osi i obrotów
Reguła prawej ręki, orientacja osi prawoskrętnego układu kartezjańskiego oraz kierunek obrotu wokół osi (kciuk = oś, palce = kierunek dodatniego obrotu).
Źródło: Wikimedia Commons · autor: User:Acdx, cmglee · licencja: CC BY-SA 4.0
(k^,θ),k^=1,θ[0,π](\hat{\mathbf{k}},\,\theta), \quad \|\hat{\mathbf{k}}\| = 1, \quad \theta \in [0, \pi]

Wzór Rodriguesa (axis-angle → macierz):

R=I+sinθ[k^]×+(1cosθ)[k^]×2R = I + \sin\theta\,[\hat{\mathbf{k}}]_\times + (1-\cos\theta)\,[\hat{\mathbf{k}}]_\times^{\,2}

gdzie [k^]×[\hat{\mathbf{k}}]_\times to macierz antysymetryczna z osi k̂:

[k^]×=[0kzkykz0kxkykx0][\hat{\mathbf{k}}]_\times = \begin{bmatrix} 0 & -k_z & k_y \\ k_z & 0 & -k_x \\ -k_y & k_x & 0 \end{bmatrix}

Wektor rotacji, zapis kompaktowy

Połącz oś i kąt w jeden wektor 3-wymiarowy:

r=θk^R3\mathbf{r} = \theta\,\hat{\mathbf{k}} \in \mathbb{R}^3

Długość wektora = kąt obrotu, kierunek = oś. To jest logarytm SO(3) w sensie algebr Liego, używamy go jako twist error w solverach iteracyjnych (moduł 3) oraz jako standard w OpenCV (cv::Rodrigues) i ROS.

Zalety: 3 liczby, gładkie odwzorowanie w okolicy zera (identyczność). Idealne do reprezentacji małych rotacji (np. w iteracjach IK lub korekcjach dryfu IMU).

Wady: nieciągłe przy θ → 0 (oś staje się nieokreślona, choć produkt θ·k̂ pozostaje gładki) i przy θ → π (dwie antypodalne osie dają tę samą rotację).

Krok 5

Kwaterniony jednostkowe, standard nowoczesnej robotyki

Najsubtelniejsza, ale najbardziej praktyczna reprezentacja. Kwaternion to czwórka liczb:

q=(w,x,y,z)=w+xi+yj+zkq = (w, x, y, z) = w + x\mathrm{i} + y\mathrm{j} + z\mathrm{k}

z mnożeniem zdefiniowanym przez Hamiltona (1843). Dla kwaternionów jednostkowych (q=1\|q\| = 1) istnieje piękna tożsamość, każdy obrót w 3D zapisuje się jako:

q=(cosθ2,  k^xsinθ2,  k^ysinθ2,  k^zsinθ2)q = \left(\cos\frac{\theta}{2},\; \hat{k}_x \sin\frac{\theta}{2},\; \hat{k}_y \sin\frac{\theta}{2},\; \hat{k}_z \sin\frac{\theta}{2}\right)

(θ\theta, k^\hat{\mathbf{k}} jak w axis-angle). Cztery liczby z jednym ograniczeniem (norma = 1) → 3 stopnie swobody, tyle ile trzeba.

Kompozycja rotacji = mnożenie kwaternionów (po regułach Hamiltona):

q12=q1q2(najpierw q2, potem q1)q_{12} = q_1 \cdot q_2 \quad\text{(najpierw } q_2\text{, potem } q_1\text{)}

Inwersja = sprzężenie (zmień znak części urojonej):

q1=(w,  x,  y,  z)(dla q=1)q^{-1} = (w,\; -x,\; -y,\; -z) \quad\text{(dla } \|q\|=1\text{)}

Zalety kwaternionów

  • Brak singularności, gimbal lock nie istnieje. Gładkie odwzorowanie do SO(3)SO(3) wszędzie.
  • Tania kompozycja, 16 mnożeń vs 27 dla macierzy 3×3.
  • Numerycznie stabilne, mała utrata jednostkowości łatwo naprawiana przez normalizację (1 dzielenie).
  • Naturalna interpolacja, SLERP („sferyczna interpolacja") daje gładkie obroty z stałą prędkością kątową.
  • Mała pamięć, 4 floats vs 9 dla macierzy.

Wady kwaternionów

  • Mniej intuicyjne, patrząc na (0.7, 0.0, 0.0, 0.7) trudno powiedzieć od razu, jaki to obrót.
  • Pokrycie podwójne, kwaterniony qq i q-q reprezentują tę samą rotację. Trzeba o tym pamiętać przy porównaniach i interpolacji (SLERP wewnętrznie sprawdza to przez iloczyn skalarny).
  • Wymaga normalizacji po długich rachunkach (1 sqrt + 4 dzielenia, tańsze niż reortonormalizacja macierzy).

SLERP, interpolacja, którą zawsze chciałeś

Sferyczna interpolacja liniowa (Spherical Linear Interpolation, Shoemake 1985), gładkie przejście między dwoma orientacjami q1q_1 i q2q_2:

slerp(q1,q2,t)=sin((1t)Ω)sinΩq1+sin(tΩ)sinΩq2\text{slerp}(q_1, q_2, t) = \frac{\sin((1-t)\Omega)}{\sin\Omega}\,q_1 + \frac{\sin(t\Omega)}{\sin\Omega}\,q_2

gdzie Ω\Omega = kąt między q1q_1 i q2q_2 w 4D. Wynik: stała prędkość kątowa od początku do końca, krótszą stroną sfery 4D. Spróbuj zinterpolować dwie orientacje suwakami w eksploratorze powyżej, kwaterniony dają zawsze ciągłą interpolację, natomiast kąty Eulera tracą ciągłość przy ±180°.

Kiedy czego używać, praktyczna ściąga

SytuacjaNajlepsza reprezentacjaDlaczego
FK, transformacje punktów, jakobianMacierzBezpośrednie mnożenie macierzy z wektorami
Wejście/wyjście z user interfaceKąty Eulera (RPY)Człowiek rozumie „przekręć o 30°"
Twist error w solverach iteracyjnychWektor rotacji (log SO(3))3 liczby, gładkie w okolicach 0, dodawanie ma sens
Interpolacja trajektoriiKwaternion (SLERP)Gładkie, stała prędkość kątowa, brak singularności
Składanie wielu rotacji w łańcuchuKwaternionTańsze i numerycznie stabilniejsze niż macierze
Komunikacja z OpenCV / ROS / niskopoziomowe sterowanieWektor rotacji lub kwaternionStandardy bibliotek
Prezentacja / wizualizacja / GUIKąty Eulera (intuicyjnie) lub axis-angleCzytelne dla człowieka
Małe korekcje (np. dryf IMU)Wektor rotacjiDodawanie ma sens dla małych θ\theta, brak nieciągłości

Dwie najczęstsze reguły praktyczne

  1. Wewnątrz silnika obliczeniowego używajjednej reprezentacji konsekwentnie: zwykle macierzy (FK, jakobian) lub kwaternionów (interpolacja, łańcuchy transformacji). Nie konwertuj tam-i-z-powrotem niepotrzebnie.
  2. Konwertuj na granicach systemu, gdy dane wchodzą lub wychodzą (UI, czujniki, biblioteki zewnętrzne), i dokumentuj konwencję. Każda zmiana konwencji to potencjalny bug.

Dla zaawansowanych: związek z algebrami Liego

Wszystkie cztery „minimalne" reprezentacje (Eulera, axis-angle, wektor rotacji, kwaternion) to różne sposoby parametryzowania rozmaitości SO(3)SO(3). Wektor rotacji ma szczególne znaczenie, jest wykładniczą mapą algebry Liego:

R=exp([r]×),r=log(R)R = \exp([\mathbf{r}]_\times), \quad \mathbf{r} = \log(R)^{\vee}

Tu exp\exp i log\log to macierzowe wykładnicze i logarytm. Wzór Rodriguesa to jest po prostu rozwinięcie szeregu Taylora dla exp na macierzach antysymetrycznych. Ten związek pozwala uogólniać metody numeryczne (np. „średnia" rotacji = średnia ich logów + powrót do SO(3) przez exp). Temat dla osobnego wykładu, w robotyce wystarczy wiedzieć, że istnieje i że biblioteki typu scipy.spatial.transform czy Sophus (C++) udostępniają te operacje gotowe.

Co dalej

Po tym module powinno być znacznie jaśniejsze, dlaczego w module 3 (jakobianowych) używamy logarytmu SO(3) jako twist error, a w module 1 (analitycznym), bezpośrednio elementów macierzy R. Każda decyzja o reprezentacji ma swoje uzasadnienie. Praktyczna wskazówka na koniec: jeśli pracujesz nad kontrolerem robota, silnikiem 3D albo systemem AR/VR, zacznij od zaimplementowania klasy Rotation ze wszystkimi pięcioma reprezentacjami (jak scipy.spatial.transform.Rotation albo three.js Quaternion) i konsekwentnie używaj tylko jednej wewnętrznej, konwertując na granicy.