-
Notifications
You must be signed in to change notification settings - Fork 30
/
jlblanco2010geometry3D_techrep.tex
executable file
·4950 lines (4005 loc) · 163 KB
/
jlblanco2010geometry3D_techrep.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
% Technical report:
% "A tutorial on SE(3) transformation parameterizations and on-manifold optimization"
% 2010-2021 Jose Luis Blanco Claraco
%
\documentclass[a4paper,11pt]{report}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{array}
\usepackage{float}
\usepackage{subfigure}
\usepackage{color}
\usepackage{listings}
\usepackage[utf8x]{inputenc}
\usepackage{wrapfig}
\usepackage{subeqnarray}
\usepackage{cancel}
\usepackage{amsfonts} % For \mathbb
\usepackage{amsthm} % For \theorem
\newtheorem{mytheorem}{Theorem}
\usepackage{fancyhdr} % Cabeceras
\usepackage{titlesec}
% ============= Fix buggy version of titlesec
\usepackage{etoolbox}
\makeatletter
\patchcmd{\ttlh@hang}{\parindent\z@}{\parindent\z@\leavevmode}{}{}
\patchcmd{\ttlh@hang}{\noindent}{}{}{}
\makeatother
% =============
\setcounter{secnumdepth}{4}
\newcommand{\Paragraph}[1]{\underline{\textbf{#1}}\\ \noindent}
\usepackage{color}
\usepackage{colortbl}
\usepackage{lastpage}
\usepackage{array}
\usepackage{multirow}
\usepackage{datetime}
\usepackage{bm} % command \bm
\usepackage{amssymb,amsmath}
\input{MAPIR_techrep_template.tex}
\newcommand{\E}{{\bm{\varepsilon}}}
\newcommand{\W}{{\bm{\omega}}}
\newcommand{\A}{{\mathbf{A}}}
\newcommand{\B}{{\mathbf{B}}}
\newcommand{\D}{{\mathbf{D}}}
\newcommand{\I}{{\mathbf{I}}}
\newcommand{\R}{{\mathbf{R}}}
\newcommand{\Pone}{\mathbf{P}_1}
\newcommand{\Ptwo}{\mathbf{P}_2}
\newcommand{\DEL}{{\bm{\delta}}}
% The hat/wedge operator: the inverse of the "vee" operator
\newcommand{\hatop}[1]{#1^\wedge}
%% This MUST BE the last include:
\usepackage[bookmarks=true,breaklinks=true,linkbordercolor={0 0 1}]{hyperref}
% \addtolength{\oddsidemargin}{-.5in}
% \addtolength{\evensidemargin}{-.5in}
% \addtolength{\textwidth}{1.0in}
\addtolength{\topmargin}{-.5in}
% \addtolength{\textheight}{1.0in}
% Title Page21
% \title{6D poses as Euler angles, transformation matrices and quaternions: equivalences, compositions and uncertainty}
% \author{Jose-Luis Blanco\\[email protected]\\~\\Technical Report\\~\\
% MAPIR Group\\University of M\'alaga, Spain}
\begin{document}
\definecolor{lightgray}{rgb}{0.93,0.93,0.93}
\definecolor{darkgray}{rgb}{0.5,0.5,0.5}
%%\lstset{frameround=fttt}
\lstset{language=C++}
\lstset{backgroundcolor=\color{lightgray}}
%% \lstset{numbers=left, numberstyle=\tiny, numbersep=5pt} %% stepnumber=2,
\lstset{keywordstyle=\color{blue}\bfseries\emph}
\lstset{commentstyle=\color{darkgray}\emph}
\lstset{basicstyle=\ttfamily\scriptsize} %%\footnotesize}
\title{}
\author{\\\\~\\Technical Report\\~\\
of M\'alaga, Spain}
\TRInfo{A tutorial on $\mathbf{SE}(3)$ transformation parameterizations and on-manifold optimization}
{José Luis Blanco Claraco\\ \begin{small} \texttt{[email protected]} \\ \url{https://w3.ual.es/personal/jlblanco/} \end{small} }
{MAPIR Group}{}{012010}{Last update: \ddmmyyyydate \today }
\PageStyle
%\maketitle
\pagestyle{plain}
\begin{abstract}
An arbitrary rigid transformation in $\mathbf{SE}(3)$ can be separated into two parts, namely,
a translation and a rigid rotation.
This technical report reviews, under a unifying viewpoint, three common alternatives to representing the
rotation part: sets of three (yaw-pitch-roll) Euler angles, orthogonal rotation matrices from
$\mathbf{SO}(3)$ and quaternions.
It will be described:
(i) the equivalence between these representations and the formulas for transforming one to each other
(in all cases considering the translational and rotational parts as a whole),
(ii) how to compose poses with poses and poses with points in each representation and
(iii) how the uncertainty of the poses (when modeled as Gaussian distributions)
is affected by these transformations and compositions.
Some brief notes are also given about the Jacobians required to implement least-squares optimization
on manifolds, an very promising approach in recent engineering literature.
The text reflects which MRPT C++ library\footnote{\texttt{https://www.mrpt.org/}} functions implement
each of the described algorithms.
All formulas and their implementation have been thoroughly validated
by means of unit testing and numerical estimation of the Jacobians.
\end{abstract}
\newpage
\begin{wrapfigure}{r}{3cm}
\includegraphics[width=2.7cm]{imgs/forkme.png}
\end{wrapfigure}
Feedback and contributions are welcome in: \\
\url{https://github.com/jlblancoc/tutorial-se3-manifold}.
\vspace{2cm}
\textbf{History of document versions:}
\begin{itemize}
\item Apr/2022: Fixed missing transpose in Eq.~(\ref{eq:oplus.ab.wrt.a}), which was correctly set in Eq.~(\ref{eq:jacob_eD.2}) (Thanks to Frisch)
\item Mar/2021: Added Eqs.~(\ref{eq:rodrigues_coordinate})--(\ref{eq:axis.angle.PR}) and
Eqs.~(\ref{eq:rotation_angle})--(\ref{eq:axis_around_pi}) (Thanks to \href{https://github.com/nurlanov-zh
}{Nurlanov Zhakshylyk}).
\item May/2020: Fix wrong terms in Eq.~\ref{eq:jacob.f_qrir_p} and a typo in Eq.~\ref{eq:jacob.inverse.quat} (Thanks to \href{https://github.com/YB27}{@YB27}).
\item Mar/2019: Added new sections: \S\ref{sect:jacob.DinvP2invP2}, \S\ref{sect:eq:jacob_dLnSE3_dSE3}. Removed incorrect transpose in Eq.~\ref{eq:oplus.ab.wrt.a}. Add appendix~\ref{ch:apx:se2} for SE(2) GraphSLAM. Formally define pseudo exponential and logarithm maps in \S\ref{eq:exp.log.se3}.
\item Oct/2018: Yaw-Pitch-Roll to Quaternion Jacobian gets its own equation number for easier reference: Eq.~\ref{eq:jac_quat_ypr}. Better references for boxplus and boxminus operators in \S\ref{ch:se3_optim}. Added \S\ref{sect:jacob.p6_p12}. Added exponential and logarithms for SO(3) in quaternion form to \S\ref{eq:exp.log.so3}.
\item 29/May/2018: Adoption of the widespread notation for the "hat" and "vee" Lie group operators, as introduced now in \S\ref{sect:mat_deriv:ops}.
\item 25/Mar/2018: Fixed minor typos.
\item 28/Nov/2017: Fixed typos in \S\ref{eq:jacob_pmA_e_D} (Thanks to \href{https://github.com/gblack007}{@gblack007}).
\item 10/Nov/2017: Sources published in GitHub: \\
\url{https://github.com/jlblancoc/tutorial-se3-manifold}.
\item 18/Oct/2017: Corrected typos in equations of \S\ref{sect:point_inv:quat} (Thanks to Otacílio Neto for detecting and reporting it).
\item 18/Oct/2016: C++ code excerpts updated to MRPT 1.3.0 or newer.
\item 8/Dec/2015: Fixed a few typos in matrix size legends.
\item 21/Oct/2014: Fixed a typo in Eq.~\ref{eq:rodrigues_ln} (Thanks to Tanner Schmidt for reporting).
\item 9/May/2013: Added the Jacobian of the SO(3) logarithm map, in \S\ref{sect:eq:jacob_dLnROT_dROT}.
\item 14/Aug/2012: Added the explicit formulas for the logarithm map of SO(3) and SE(3),
fixed error in Eq.~(\ref{eq:jacob_p_min_eD_e}), explained the equivalence between the yaw-pitch-roll
and roll-pitch-yaw forms and introduction of the $\left[ \log \mathbf{R} \right]^\vee$ notation
when discussing the logarithm maps.
\item 12/Sep/2010: Added more Jacobians (\S\ref{sect:jacob_eDp},
\S\ref{sect:jacob_eDp_inv}, \S\ref{sect:jacob_De}),
the Appendix \ref{ch:apx:cv} and approximation in \S\ref{eq:jacob_A_e_D_p}.
\item 1/Sep/2010: First version.
\end{itemize}
\vfill
\textbf{Notice:} \\
Part of this report was also published within chapter 10 and appendix IV of the
book \cite{madrigal2012slambook}.
\vspace{1cm}
\begin{scriptsize}
\begin{center}
\includegraphics[width=3cm]{imgs/by-nc-sa.pdf}
\\
This work is licensed under
Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
License.
\end{center}
\end{scriptsize}
\newpage
\tableofcontents
%% ================================================
\chapter{Rigid transformations in 3D}
\section{Basic definitions}
\label{sect:basic}
This report focuses on geometry for the most interesting case of an Euclidean space in
engineering: the three-dimensional space $\mathbb{R}^3$.
Over this space one can define an arbitrary \emph{transformation} through
a function or mapping:
\begin{equation}
f: \quad \mathbb{R}^3 \rightarrow \mathbb{R}^3
\end{equation}
For now, assume that $f$ can be any $3 \times 3$ matrix $\mathbf{R}$,
such as the mapping function
from a point $\mathbf{x_1}=[x_1 ~ y_1 ~ z_1]^\top$ to $\mathbf{x_2}=[x_2 ~ y_2 ~ z_2]^\top$ is simply:
\begin{equation}
\left(
\begin{array}{c}
x_2 \\ y_2 \\ z_2
\end{array}
\right)
=
\mathbf{x_2}
=
\mathbf{R} \mathbf{x_1}
=
\mathbf{R}
\left(
\begin{array}{c}
x_1 \\ y_1 \\ z_1
\end{array}
\right)
\end{equation}
The set of all invertible $3 \times 3$ matrices forms the
general linear group $\mathbf{GL}(3,\mathbb{R})$.
From all the infinite possibilities for $\mathbf{R}$, the set
of \emph{orthogonal matrices} with determinant of $\pm 1$
(i.e. $\mathbf{R}\mathbf{R}^\top=\mathbf{R}^\top\mathbf{R} = \mathbf{I_3}$)
forms the so called \emph{orthogonal group} or $\mathbf{O}(3) \subset \mathbf{GL}(3,\mathbb{R})$.
Note that the group operator is the standard matrix product, since multiplying
any two matrices from $\mathbf{O}(3)$ gives another member of $\mathbf{O}(3)$.
All these matrices define \emph{isometries}, that is, transformations that
preserve distances between any pair of points.
From all the isometries, we are only interested here in those with a
determinant of $+1$, named \emph{proper} isometries.
They constitute the group of proper orthogonal transformations, or
\emph{special orthogonal group} $\mathbf{SO}(3) \subset \mathbf{O}(3)$
\cite{gallier2001geometric}.
The group of matrices in $\mathbf{SO}(3)$ represents \emph{pure} rotations only.
In order to also handle translations, we can take into account $4 \times 4$
transformation matrices $\mathbf{T}$ and extend 3D points with a fourth
\emph{homogeneous} coordinate (which in this report will be always the unity),
thus:
\begin{eqnarray}
\left(
\begin{array}{c}
\mathbf{x_2} \\ 1
\end{array}
\right)
&=&
\mathbf{T}
\left(
\begin{array}{c}
\mathbf{x_1} \\ 1
\end{array}
\right)
\nonumber \\
\label{eq:x2_T_x1}
\left(
\begin{array}{c}
x_2 \\ y_2 \\ z_2 \\ 1
\end{array}
\right)
&=&
\left(
\begin{array}{c|c}
\mathbf{R} &
\begin{array}{c}
t_x \\ t_y \\ t_z
\end{array} \\
\hline
\begin{array}{ccc}
0 & 0 & 0
\end{array}
&
1
\end{array}
\right)
\left(
\begin{array}{c}
x_1 \\ y_1 \\ z_1 \\ 1
\end{array}
\right)
\\
\mathbf{x_2} &=& \mathbf{R} \mathbf{x_1} +
\left(
t_x ~~ t_y ~~ t_z
\right)^\top \nonumber
\end{eqnarray}
In general, any invertible $4 \times 4$ matrix belongs to the
general linear group $\mathbf{GL}(4,\mathbb{R})$, but in the particular case of
the so defined set of transformation matrices $\mathbf{T}$
(along with the group operation of matrix product),
they form the group of affine rigid motions which, with \emph{proper} rotations
($|\mathbf{R}|=+1$), is denoted as the special Euclidean group $\mathbf{SE}(3)$.
It turns out that $\mathbf{SE}(3)$ is also a Lie group, and
a manifold with structure $\mathbf{SO}(3) \times \mathbb{R}^3$ (see \S\ref{sect:lie:linear}).
Chapters \ref{chap:mat_deriv}-\ref{ch:se3_optim} will explain
what all this means and how to exploit it in engineering optimization problems.
In this report we will refer to $\mathbf{SE}(3)$ transformations as \emph{poses}.
As seen in Eq.~(\ref{eq:x2_T_x1}), a pose can be described by means of a 3D translation
plus an orthonormal vector base (the columns of $\mathbf{R}$),
or coordinate frame, relative to any other arbitrary coordinate reference system.
The overall number of degrees of freedom is six, hence they can be also referred
to as \emph{6D poses}.
The Figure~\ref{fig:1} illustrates this definition, where the pose $\mathbf{p}$ is represented
by the axes $\{\mathbf{X}',\mathbf{Y}',\mathbf{Z}' \}$ with respect to a reference frame
$\{\mathbf{X},\mathbf{Y},\mathbf{Z} \}$.
\begin{figure}[h!]
\centering
\includegraphics[width=0.70\textwidth]{imgs/fig_pose_composition.pdf}
\caption{Schematic representation of a 6D pose $\mathbf{p}$ and its role in defining
the relative coordinates $\mathbf{a}'$ of the 3D point $\mathbf{a}$.}
\label{fig:1}
\end{figure}
Given a 6D pose $\mathbf{p}$ and a 3D point $\mathbf{a}$, both relative to some arbitrary
global frame of reference, and being $\mathbf{a}'$ the coordinates of $\mathbf{a}$ relative
to $\mathbf{p}$, we define
the composition $\oplus$ and inverse composition $\ominus$ operations as follows:
\begin{eqnarray*}
\mathbf{a} & \equiv & \mathbf{p} \oplus \mathbf{a}' ~~~~~~~ \textrm{Pose composition} \\
\mathbf{a'} & \equiv & \mathbf{a} \ominus \mathbf{p} ~~~~~~~~ \textrm{Pose inverse composition} \\
\end{eqnarray*}
These operations are intensively applied in a number of robotics and computer vision
problems, for example, when computing the relative position of a 3D visual landmark
with respect to a camera while computing the perspective projection of the landmark
into the image plane.
The composition operators can be also applied to pairs of 6D poses (above we described a combination
of \emph{6D poses} and {3D points}).
The meaning of composing two poses $\mathbf{p1}$ and $\mathbf{p2}$
obtaining a third pose $\mathbf{p} = \mathbf{p1} \oplus \mathbf{p2}$
is that of concatenating the transformation of the second pose to the reference system
\emph{already transformed} by the first pose.
This is illustrated in Figure~\ref{fig:comp_2poses}.
\begin{figure}[h!]
\centering
\subfigure[The pose $\mathbf{p1}$]{\includegraphics[width=0.4\textwidth]{imgs/pose_comp_p1.pdf}}
\subfigure[The pose $\mathbf{p2}$]{\includegraphics[width=0.4\textwidth]{imgs/pose_comp_p2.pdf}} \\
\subfigure[Composition $\mathbf{p1} \oplus \mathbf{p2}$]{\includegraphics[width=0.6\textwidth]{imgs/pose_comp_p1p2.pdf}}
\caption{The composition of two 6D poses $\mathbf{p1}$ and $\mathbf{p2}$ leads to $\mathbf{p}$.}
\label{fig:comp_2poses}
\end{figure}
The inverse pose composition can be also applied to 6D poses, in this case meaning that
the pose $\mathbf{p}$ (in global coordinates) ``is seen'' as $\mathbf{p2}$ with respect
to the reference frame of $\mathbf{p1}$ (this one, also in global coordinates), a
relationship expressed as $\mathbf{p2} = \mathbf{p} \ominus \mathbf{p1}$.
Up to this point, poses, pose/point and pose/pose compositions have been mostly described
under a purely geometrical point of view.
The next section introduces some of the most commonly employed parameterizations.
\newpage
\section{Common parameterizations}
\subsection{3D translation plus yaw-pitch-roll (3D+YPR)}
A 6D pose $\mathbf{p_6}$ can be described as a displacement in 3D plus a rotation defined by
means of a specific case of Euler angles: yaw ($\phi$), pitch
($\chi$) and roll ($\psi$), that is:
\begin{eqnarray}
\mathbf{p_6} &=& [x ~ y ~ z ~ \phi ~ \chi ~ \psi]^\top
\end{eqnarray}
The geometrical meaning of the angles is represented in Figure~\ref{fig:ypr}.
There are other alternative conventions about triplets of angles to represent a rotation in 3D, but
the one employed here is the one most commonly used in robotics.
\begin{figure}[h]
\centering
\includegraphics[width=0.40\textwidth]{imgs/fig1.pdf}
\caption{A common convention for the angles yaw, pitch and roll.}
\label{fig:ypr}
\end{figure}
Note that the overall rotation is represented as a sequence of three individual rotations,
each taking a different axis of rotation.
In particular, the order is: yaw around the Z axis, then pitch around the \emph{modified} Y axis,
then roll around the \emph{modified} X axis. It is also common to find in the literature
the roll-pitch-yaw (RPY) parameterization (versus YPR), where rotations apply over the same angles (e.g. yaw
around the Z axis) but in inverse order and around the \emph{unmodified} axes instead of
the successively modified axes of the yaw-pitch-roll form. In any case, it can be shown that
the numeric values of the three rotations are identical for any given 3D rotation \cite{madrigal2012slambook},
thus both forms are completely equivalent.
This representation is the most compact since it only requires 6 real parameters
to describe a pose (the minimum number of parameters, since a pose has 6 degrees of freedom).
However, in some applications it may be more advantageous to employ other representations,
even at the cost of maintaining more parameters.
\subsubsection{Degenerate cases: gimbal lock}
\label{sect:ypr:gimbal}
One of the important disadvantages of the yaw-pitch-roll representation of rotations is the existence
of two degenerate cases, specifically, when pitch ($\chi$) approaches $\pm 90^\circ$. In this case,
it is easy to realize that a change in roll becomes a change in yaw.
This means that, for $ \chi = \pm 90^\circ$, there is not a unique correspondence between any possible
rotation in 3D and a triplet of yaw-pitch-roll angles.
The practical consecuences of this characteristic is the need for detecting and handling these
special cases, as will be seen in some of the transformations described later on.
\subsubsection{Implementation in MRPT}
Poses based on yaw-pitch-roll angles are implemented in the C++ class \texttt{mrpt::poses::CPose3D}:
\begin{lstlisting}
#include <mrpt/poses/CPose3D.h>
using namespace mrpt::poses;
using mrpt::utils::DEG2RAD;
CPose3D p(1.0 /* x */,2.0 /* y */,3.0 /* z */,
DEG2RAD(30.0) /* yaw */, DEG2RAD(20.0) /* pitch */, DEG2RAD(90.0) /* roll */ );
\end{lstlisting}
%\newpage
\subsection{3D translation plus quaternion (3D+Quat)}
A pose $\mathbf{p_7}$ can be also described with a displacement in 3D plus a rotation
defined by a quaternion, that is:
\begin{eqnarray}
\mathbf{p_7} &=& [x ~ y ~ z ~ q_r ~ q_x ~ q_y ~ q_z ] ^ \top
\end{eqnarray}
\noindent where the unit quaternion elements are $[q_r, (q_x,q_y,q_z)]$. A useful interpretation of quaternions
is that of a rotation of $\theta$ radians around the axis defined by the vector $\vec{v} = (v_x,v_y,v_z) \propto (q_x,q_y,q_z)$.
The relation between $\theta$, $\vec{v}$ and the elements in the quaternion is:
\begin{equation*}
\begin{array}{cc}
q_r = \cos\frac{\theta}{2} &
\begin{array}{rcl}
q_x &=& \sin\frac{\theta}{2} v_x \\
q_y &=& \sin\frac{\theta}{2} v_y \\
q_z &=& \sin\frac{\theta}{2} v_z
\end{array}
\end{array}
\end{equation*}
This interpretation is also represented in Figure~\ref{fig:quat}.
The convention is $q_r$ (and thus $\theta$) to be non-negative.
A quaternion has 3 degrees of freedom in spite of having four components
due to the unit length constraint, which can be interpreted as a unit hyper-sphere,
hence its topology being that of the special unitary group $SU(2)$, diffeomorphic to $S(3)$.
\begin{figure}[h]
\centering
\includegraphics[width=0.50\textwidth]{imgs/quaternion.pdf}
\caption{A quaternion can be seen as a rotation around an arbitrary 3D axis.}
\label{fig:quat}
\end{figure}
\subsubsection{Implementation in MRPT}
Poses based on quaternions are implemented in the class \texttt{mrpt::poses::CPose3DQuat}.
The quaternion part of the pose is always normalized (i.e. $q_r^2+q_x^2+q_y^2+q_z^2=1$).
\begin{lstlisting}
#include <mrpt/poses/CPose3DQuat.h>
using namespace mrpt::poses;
using namespace mrpt::math;
CPose3DQuat p(1.0 /* x */,2.0 /* y */,3.0 /* z */,
CQuaternionDouble(1.0 /* qr */, 0.0,0.0,0.0 /* vector part */) );
\end{lstlisting}
\subsubsection{Normalization of a quaternion}
\label{sect:quat:norm}
In many situations, the quaternion part of a 3D+Quat 7D representation
of a pose may drift away of being unitary.
This is specially true if each component of the quaternion is estimated
independently, such as within a Kalman filter or
any other Gauss-Newton iterative optimizer
(for an alternative, see \S\ref{ch:se3_optim}).
The normalization function is simply:
\begin{equation}
\mathbf{q'}(\mathbf{q})
=
\left(
\begin{array}{c}
q_r' \\ q_x'\\ q_y'\\ q_z'
\end{array}
\right)
=
\frac{\mathbf{q}}{|\mathbf{q}|}
=
\frac{1}{(q_r^2+q_x^2+q_y^2+q_z^2)^{1/2}}
\left(
\begin{array}{c}
q_r \\ q_x\\ q_y\\ q_z
\end{array}
\right)
\end{equation}
\noindent and its $4 \times 4$ Jacobian is given by:
\begin{equation}
\frac{\partial \mathbf{q'}(q_r,q_x,q_y,q_z)}{\partial q_r,q_x,q_y,q_z}
=
\frac{1}{(q_r^2+q_x^2+q_y^2+q_z^2)^{3/2}}
\left(
\begin{array}{cccc}
q_x^2 +q_y^2+q_z^2 & -q_r q_x & -q_r q_y & -q_r q_z \\
-q_x q_r & q_r^2 +q_y^2+q_z^2 & -q_x q_y & - q_x q_z \\
-q_y q_r & -q_y q_x & q_r^2 +q_x^2 +q_z^2 & -q_y q_z \\
-q_z q_r & -q_z q_x & -q_z q_y & q_r^2+q_x^2+q_y^2
\end{array}
\right)
\end{equation}
%\newpage
%
\subsection{$4 \times 4$ transformation matrices}
Any rigid transformation in 3D can be described by means of a $4 \times 4$
matrix $\mathbf{P}$ with the following structure:
\begin{equation}
\mathbf{P}=\left(
\begin{array}{ccc|c}
& & & x \\
& \mathbf{R} & & y \\
& & & z \\ \hline
0 & 0 & 0& 1
\end{array}
\right)
\end{equation}
\noindent where the $3 \times 3$ orthogonal matrix $\mathbf{R} \in \mathbf{SO}(3)$
is the \emph{rotation matrix}\footnote{Also called direction cosine matrix (DCM).}
(the only part of $\mathbf{P}$ related to
the 3D rotation) and the vector $(x,y,z)$ represents the translational part of the 6D pose.
For such a matrix to be applicable to 3D points, they must be first represented in
homogeneous coordinates \cite{bloomenthal1994homogeneous} which, in our case, will consist in just considering a fourth,
extra dimension to each point which will be always equal to the unity -- examples of this will be discussed later on.
\subsubsection{Implementation in MRPT}
Transformation matrices themselves can be managed as any other normal $4\times 4$ matrix:
\begin{lstlisting}
#include <mrpt/utils/types_math.h>
using namespace mrpt::math;
CMatrixDouble44 P;
\end{lstlisting}
Note however that the 3D+YPR type \texttt{CPose3D} also holds a cached matrix representation
of the transformation which can be retrieved with \texttt{CPose3D::getHomogeneousMatrix()}.
%% ================================================
\chapter{Equivalences between representations}
In this chapter the focus will be on the transformation of the rotational
part of 6D poses, since the 3D translational part is always represented as an
unmodified vector in all the parameterizations.
Another point to be discussed here is how the transformation between different
parameterizations affects the \emph{uncertainty} for the case of probability distributions over poses.
Assuming a multivariate Gaussian model, first order
linearization of the transforming functions
is proposed as a simple and effective approximation.
In general, having a multivariate Gaussian distribution of the variable
$\mathbf{x} \sim N(\bar{\mathbf{x}},\mathbf{\Sigma_x})$ (where $\bar{x}$ and $\mathbf{\Sigma_x}$
are its mean and covariance matrix, respectively), we can approximate
the distribution of $\mathbf{y} = f(\mathbf{x})$ as another Gaussian
with parameters:
\begin{eqnarray}
\bar{\mathbf{y}} &=& f(\bar{\mathbf{x}}) \\
\mathbf{\Sigma_y} &=&
\left.\frac{\partial f(\mathbf{x})}{\partial \mathbf{x}}\right|_{\mathbf{x}=\bar{\mathbf{x}}}
\mathbf{\Sigma_x}
\left.\frac{\partial f(\mathbf{x})}{\partial \mathbf{x}}\right|_{\mathbf{x}=\bar{\mathbf{x}}}^\top
\end{eqnarray}
Note that an alternative to this method is using the scaled unscented
transform (SUT) \cite{julier2002sut}, which may give more exact results for
large levels of the uncertainty but typically requires more computation time
and can cause problems for semidefinite positive (in contrast to definite positive)
covariance matrices.
\section{3D+YPR to 3D+Quat }
\label{sect:ypr2quat}
\subsection{Transformation}
Any given rotation described as a combination of yaw ($\phi$),
pitch ($\chi$) and roll ($\psi$) can
be expressed as a quaternion with components $(q_r, q_x,q_y,q_z)$
given by \cite{horn2001some}:
\begin{eqnarray}
\mathbf{q}(\phi,\chi,\psi) &=&
\begin{bmatrix}
q_r(\phi,\chi,\psi) \\
q_x(\phi,\chi,\psi) \\
q_y(\phi,\chi,\psi) \\
q_z(\phi,\chi,\psi)
\end{bmatrix}
\quad \quad
\mathbf{q}(\phi,\chi,\psi) : \mathcal{R}^3 \rightarrow \mathcal{R}^4
\\
q_r(\phi,\chi,\psi) &=& \cos\frac{\psi}{2} \cos\frac{\chi}{2} \cos\frac{\phi}{2} +
\sin\frac{\psi}{2} \sin\frac{\chi}{2} \sin\frac{\phi}{2} \\
q_x(\phi,\chi,\psi) &=& \sin\frac{\psi}{2} \cos\frac{\chi}{2} \cos\frac{\phi}{2} -
\cos\frac{\psi}{2} \sin\frac{\chi}{2} \sin\frac{\phi}{2} \\
q_y(\phi,\chi,\psi) &=& \cos\frac{\psi}{2} \sin\frac{\chi}{2} \cos\frac{\phi}{2} +
\sin\frac{\psi}{2} \cos\frac{\chi}{2} \sin\frac{\phi}{2} \\
q_z(\phi,\chi,\psi) &=& \cos\frac{\psi}{2} \cos\frac{\chi}{2} \sin\frac{\phi}{2} -
\sin\frac{\psi}{2} \sin\frac{\chi}{2} \cos\frac{\phi}{2}
\end{eqnarray}
\subsubsection{Implementation in MRPT}
Transformation of a \texttt{CPose3D} pose object based on yaw-pitch-roll angles
into another of type \texttt{CPose3DQuat} based on quaternions can be done transparently
due the existence of an implicit conversion constructor:
\begin{lstlisting}
#include <mrpt/poses/CPose3D.h>
#include <mrpt/poses/CPose3DQuat.h>
using namespace mrpt::poses;
CPose3D p6;
...
CPose3DQuat p7 = CPose3DQuat(p6); // Transparent conversion
\end{lstlisting}
\subsection{Uncertainty}
Given a Gaussian distribution over a 6D pose in yaw-pitch-roll form with
mean ${\mathbf{\bar{p}_6}}$ and being $cov(\mathbf{p_6})$ its $6 \times 6$ covariance matrix,
the $7 \times 7$ covariance matrix of the equivalent quaternion-based form
is approximated by:
\begin{equation}
cov(\mathbf{p_7}) =
\frac{\partial \mathbf{p_7}(\mathbf{p_6}) }{\partial \mathbf{p_6}} ~
cov(\mathbf{p_6}) ~
\frac{\partial \mathbf{p_7}(\mathbf{p_6}) }{\partial \mathbf{p_6}}^\top
\end{equation}
\noindent where the Jacobian matrix is given by:
\begin{subeqnarray}
\label{eq:jac_p7_p6}
\frac{\partial \mathbf{p_7}(\mathbf{p_6}) }{\partial \mathbf{p_6}} &=&
\left(
\begin{array}{c|cc}
\mathbf{I_3} & \mathbf{0_{3\times 3}} \\ \hline
\mathbf{0_{4\times 3}} & \frac{\partial \mathbf{q}(\phi,\chi,\psi) }{\partial \{ \phi,\chi,\psi \} }
\end{array}
\right)_{7 \times 6}
\\
\slabel{eq:jac_quat_ypr}
\frac{\partial \mathbf{q}(\phi,\chi,\psi) }{\partial \{ \phi,\chi,\psi \} } &=&
\begin{bmatrix}
(ssc-ccs)/2 & (scs-csc)/2 & (css-scc)/2 \\
-(csc+scs)/2 & -(ssc+ccs)/2 & (ccc+sss)/2 \\
(scc-css)/2 & (ccc-sss)/2 & (ccs-ssc)/2 \\
(ccc+sss)/2 & -(css+scc)/2 & -(csc+scs)/2
\end{bmatrix} _{4 \times 3}
\end{subeqnarray}
\noindent where the following abbreviations have been used:
\begin{equation*}
\begin{array}{ccc}
ccc = \cos\frac{\psi}{2}\cos\frac{\chi}{2}\cos\frac{\phi}{2} &
ccs = \cos\frac{\psi}{2}\cos\frac{\chi}{2}\sin\frac{\phi}{2} &
csc = \cos\frac{\psi}{2}\sin\frac{\chi}{2}\cos\frac{\phi}{2} \\
& ... & \\
scc = \sin\frac{\psi}{2}\cos\frac{\chi}{2}\cos\frac{\phi}{2} &
ssc = \sin\frac{\psi}{2}\sin\frac{\chi}{2}\cos\frac{\phi}{2} &
sss = \sin\frac{\psi}{2}\sin\frac{\chi}{2}\sin\frac{\phi}{2} \\
\end{array}
\end{equation*}
\subsubsection{Implementation in MRPT}
Gaussian distributions over 6D poses described as yaw-pitch-roll and quaternions
are implemented in the classes \texttt{CPose3DPDFGaussian} and \texttt{CPose3DQuatPDFGaussian}, respectively.
Transforming between them is possible via an explicit transform constructor, which
converts both the mean and the covariance matrix:
\begin{lstlisting}
#include <mrpt/poses/CPose3DPDFGaussian.h>
#include <mrpt/poses/CPose3DQuatPDFGaussian.h>
using namespace mrpt::poses;
CPose3DPDFGaussian p6( p6_mean, p6_cov );
...
CPose3DQuatPDFGaussian p7 = CPose3DQuatPDFGaussian(p6); // Explicit constructor
\end{lstlisting}
%% ------------------
\section{3D+Quat to 3D+YPR }
\subsection{Transformation}
As mentioned in \S \ref{sect:ypr:gimbal}, the existence of degenerate cases in
the yaw-pitch-roll representation forces us to consider special cases in many formulas,
as it happens in this case when a quaternion must be converted into these angles.
Firstly, assuming a normalized quaternion, we define the \emph{discriminant} $\Delta$ as:
\begin{equation}
\Delta = q_r q_y - q_x q_z
\end{equation}
Then, in most situations we will have $|\Delta|<1/2$, hence we can recover the
yaw ($\phi$),
pitch ($\chi$) and roll ($\psi$) angles as:
\begin{eqnarray}
\left\{
\begin{array}{rcl}
\phi &=& \tan^{-1} \left( 2 \frac{q_r q_z + q_x q_y}{1-2(q_y^2+q_z^2)} \right) \nonumber \\
\chi &=& \sin^{-1} \left( 2 \Delta \right) \label{eq:quat2ypr_1} \\
\psi &=& \tan^{-1} \left( 2 \frac{q_r q_x + q_y q_z}{1-2(q_x^2+q_y^2)} \right) \nonumber
\end{array}
\right.
\end{eqnarray}
\noindent which can be obtained from trigonometric identities and
the transformation matrices associated to a quaternion and a triplet of angles yaw-pitch-roll
(see \S \ref{sect:ypr2mat}--\ref{sect:quat2mat}).
On the other hand, the special cases when $|\Delta| \approx 1/2$ can be solved as:
\begin{equation}
\begin{array}{c|c}
\Delta = -1/2 & \Delta = 1/2 \\ \hline
\begin{array}{rcl}
\phi &=& 2 \tan^{-1} \frac{q_x}{q_r} \\
\chi &=& -\pi /2 \\
\psi &=& 0
\end{array}
&
\begin{array}{rcl}
\phi &=& -2 \tan^{-1} \frac{q_x}{q_r} \\
\chi &=& \pi /2 \\
\psi &=& 0
\end{array}
\end{array}
\label{eq:quat2ypr_2}
\end{equation}
\subsubsection{Implementation in MRPT}
Transforming a 6D pose from a quaternion to a yaw-pitch-roll representation is
achieved transparently via an implicit transform constructor:
\begin{lstlisting}
#include <mrpt/poses/CPose3D.h>
#include <mrpt/poses/CPose3DQuat.h>
using namespace mrpt::poses;
CPose3DQuat p7;
...
CPose3D p6 = p7; // Transformation
\end{lstlisting}
\subsection{Uncertainty}
Given a Gaussian distribution over a 7D pose in quaternion form with
mean ${\mathbf{\bar{p}_7}}$ and being $cov(\mathbf{p_7})$ its $7 \times 7$ covariance matrix,
we can estimate the $6 \times 6$ covariance matrix of the equivalent yaw-pitch-roll-based
form by means of:
\begin{equation}
cov(\mathbf{p_6}) =
\frac{\partial \mathbf{p_6}(\mathbf{p_7}) }{\partial \mathbf{p_7}} ~
cov(\mathbf{p_7}) ~
\frac{\partial \mathbf{p_6}(\mathbf{p_7}) }{\partial \mathbf{p_7}}^\top
\end{equation}
\noindent where the Jacobian matrix has the following block structure:
\begin{equation}
\label{eq:jac_p6_p7}
\frac{\partial \mathbf{p_6}(\mathbf{p_7}) }{\partial \mathbf{p_7}} =
\left(
\begin{array}{c|c}
\mathbf{I_3} & \mathbf{0_{3\times 4}} \\ \hline
\mathbf{0_{3\times 3}} & \frac{\partial (\phi,\chi,\psi)(q_r,q_x,q_y,q_z)}{\partial q_r,q_x,q_y,q_z}
\end{array}
\right)_{6 \times 7}
\end{equation}
In turn, the bottom-right sub-Jacobian matrix must account for two consecutive transformations:
normalization of the Jacobian (since each element has an uncertainty, but we need it normalized
for the transformation formulas to hold), then transformation to yaw-pitch-roll form. That is:
\begin{equation}
\frac{\partial (\phi,\chi,\psi)(q_r,q_x,q_y,q_z)}{\partial q_r,q_x,q_y,q_z} =
\frac{\partial (\phi,\chi,\psi)(q_r',q_x',q_y',q_z')}{\partial q_r',q_x',q_y',q_z'}
\frac{\partial (q_r',q_x',q_y',q_z')(q_r,q_x,q_y,q_z)}{\partial q_r,q_x,q_y,q_z}
\end{equation}
\noindent where the second term in the product is the Jacobian of the quaternion
normalization (see \S \ref{sect:quat:norm}). Here, and in the rest of this report,
it can be replaced by an identity Jacobian $\mathbf{I}_4$ if it is known for sure that
the quaternion is normalized.
Regarding the first term in the product, it is the
Jacobian of the functions in Eq. \ref{eq:quat2ypr_1}--\ref{eq:quat2ypr_2}, taking
into account that it can take three different forms for the cases $\chi=90^\circ$,
$\chi=-90^\circ$ and $|\chi| \neq 90^\circ$.
\subsubsection{Implementation in MRPT}
This conversion can be achieved by means of an explicit transform constructor, as shown below:
\begin{lstlisting}
#include <mrpt/poses/CPose3DQuat.h>
#include <mrpt/poses/CPose3DQuatPDFGaussian.h>
using namespace mrpt::poses;
using namespace mrpt::math;
CPose3DQuat p7_mean = ...
CMatrixDouble77 p7_cov = ...
CPose3DQuatPDFGaussian p7(p7_mean,p7_cov);
...
CPose3DPDFGaussian p6 = CPose3DPDFGaussian(p7); // Explicit constructor
\end{lstlisting}
\section{3D+YPR to matrix }
\label{sect:ypr2mat}
\subsection{Transformation}
The transformation matrix associated to a 6D pose given in yaw-pitch-roll form has this structure:
\begin{equation}
\mathbf{P}(x,y,z,\phi,\chi,\psi)=\left(
\begin{array}{ccc|c}
& & & x \\
& \mathbf{R}(\phi,\chi,\psi) & & y \\
& & & z \\ \hline
0 & 0 & 0& 1
\end{array}
\right)
\label{eq:matP_ypr}
\end{equation}
\noindent where the $3 \times 3$ rotation matrix $\mathbf{R}$ can be easily derived
from the fact that each of the three individual rotations (yaw, pitch and roll) operate
consecutively one after the other, i.e. over the already modified axis.
This can be achieved by right-side multiplication of the individual rotation matrices:
\begin{eqnarray}
\mathbf{R}_z(\phi) &=&
\left(
\begin{array}{ccc}
\cos \phi & -\sin \phi & 0 \\
\sin \phi & \cos \phi & 0 \\
0 & 0 & 1
\end{array}
\right) \quad \mathrm{\text{Yaw rotates around Z}} \\
\mathbf{R}_y(\chi) &= &
\left(
\begin{array}{ccc}
\cos \chi & 0 & \sin \chi \\
0 & 1 & 0 \\
-\sin \chi & 0 & \cos \chi
\end{array}
\right) \quad \mathrm{\text{Pitch rotates around Y}} \\
\mathbf{R}_x(\psi) &=&
\left(
\begin{array}{ccc}
1 & 0 & 0 \\
0 & \cos \psi & -\sin \psi \\
0 & \sin \psi & \cos \psi
\end{array}
\right) \quad \mathrm{\text{Roll rotates around X}}
\end{eqnarray}
\noindent thus, concatenating them in the proper order ($\mathbf{R}_x$, then $\mathbf{R}_y$, then $\mathbf{R}_z$)
we obtain the complete rotation matrix:
\begin{eqnarray}
\mathbf{R}(\phi,\chi,\psi) &=& \mathbf{R}_z(\phi) \mathbf{R}_y(\chi) \mathbf{R}_x(\psi)
\label{eq:mat_ypr} \\
&=&
\left(
\begin{array}{ccc}
\cos \phi \cos \chi & \cos \phi \sin \chi \sin \psi - \sin \phi \cos \psi & \cos \phi \sin \chi \cos \psi + \sin \phi \sin \psi \\
\sin \phi \cos \chi & \sin \phi \sin \chi \sin \psi + \cos \phi \cos \psi & \sin \phi \sin \chi \cos \psi - \cos \phi \sin \psi \\
-\sin \chi & \cos \chi \sin \psi & \cos \chi \cos \psi
\end{array}
\right) \nonumber
\end{eqnarray}
A transformation matrix $\mathbf{P}$ is always well-defined and does not suffer of degenerate cases, but its large
storage requirements ($4\times 4=16$ elements) makes more advisable to use other representations such
as 3D+YPR (3+3=6 elements) or 3D+Quat (3+4=7 elements) in many situations.
An important exception is the case when computation time is critical and the most common operation
is composing (or inverse composing) a pose with a 3D point, where matrices require about half the
computation time than the other methods. On the other hand, composing a pose with another pose is
a slightly more efficient operation to carry out with a 3D+Quat representation.
In any case, when dealing with uncertainties, transformation matrices are not a
reasonable choice due to the
quadratic cost of keeping their covariance matrices.
The most common representation of a 6D pose with uncertainty in the literature
are 3D+Quat forms (e.g. see \cite{davison2007mrt}), thus
we will not describe how to
obtain covariance matrices of a transformation matrix here.
Note however that Jacobians of matrices are sometimes handy
as intermediaries (see \S\ref{chap:mat_deriv} and \S\ref{ch:se3_optim}).
\subsubsection{Implementation in MRPT}
The transformation matrix of any yaw-pitch-roll-based 6D pose stored in a
\texttt{CPose3D} class can be obtained as follows:
\begin{lstlisting}
#include <mrpt/poses/CPose3D.h>
using namespace mrpt::math;
using namespace mrpt::poses;
CPose3D p;
CMatrixDouble44 M = p.getHomogeneousMatrixVal();
\end{lstlisting}