NOTE / 8/23/2018
[SLAM 14 Lectures] Chapter 3 Summary
I have been reading 14 Lectures on Visual SLAM and use this note to record key points.
Rigid-body motion in 3D space
Vector dot product:
Vector cross product:
Its magnitude is . The cross product describes the rotation of a vector; think of its axis of rotation.
Euclidean transformation between coordinate frames: representations of the same vector in different coordinate systems satisfy
Multiplying both sides by
gives
This introduces the rotation matrix . A rotation matrix is orthogonal—its inverse is its transpose—and the set of rotation matrices is the special orthogonal group:
For convenient computation, introduce homogeneous coordinates and the homogeneous transformation matrix. Transformation matrices belong to the special Euclidean group:
A rotation matrix uses nine values for six degrees of freedom, which is redundant and inconvenient in optimization. Rotation vectors and Euler angles are therefore introduced.
Rotation vector / axis-angle. Any rotation can be represented by an axis and rotation angle . The rotation vector is . Rodrigues’ formula converts between axis-angle and a rotation matrix:
Euler angles are more intuitive and can use ZYX, ZYZ, XYZ, and other conventions, but they suffer from gimbal lock.
Any 3D-rotation representation using only three real numbers has singularities. Euler angles, axis-angle, and Lie algebra coordinates all have this issue.
Quaternions solve this compactly without singularities. Any rotation can be represented by two opposite quaternions; one quaternion uniquely determines a rotation.
Common Eigen operations
For matrices whose dimensions are unknown at compile time:
Initialize with
Eigen::MatrixXd matrix;, then dynamically allocate withmatrix.resize(m, n).
Solving the linear system with Eigen:
x = A.ldlt().solve(b); // A symmetric positive semidefinite. #include <Eigen/Cholesky>
x = A.llt().solve(b); // A symmetric positive definite. #include <Eigen/Cholesky>
x = A.lu().solve(b); // Stable and fast. #include <Eigen/LU>
x = A.qr().solve(b); // No pivoting. #include <Eigen/QR>
x = A.svd().solve(b); // Stable, slowest. #include <Eigen/SVD>
// .ldlt() -> .matrixL() and .matrixD()
// .llt() -> .matrixL()
// .lu() -> .matrixL() and .matrixU()
// .qr() -> .matrixQ() and .matrixR()
// .svd() -> .matrixU(), .singularValues(), and .matrixV()