Main Goal:
- Learn the rigid body geometry in 3D: rotational matrix, transformation matrix, quaternion and Euler angle.
- Learn Eigen library matrix and geometry module
I. 3D RIGID BODY MOTION
In the context of matrices, 3D rigid body motion refers to representing the movement of a solid object in three-dimensional space using transformation matrices. A rigid body motion is a transformation that preserves the shape and size of the object. It involves both translation and rotation. In this representation, a 3D rigid body motion can be described by a 4x4 transformation matrix. The upper-left 3x3 submatrix represents the rotation of the object, while the rightmost column represents the translation. By multiplying this transformation matrix with the coordinates of points or vectors in the object’s local coordinate system, the new coordinates in the global coordinate system can be obtained.
1.1 Properties of Matrix
- Definition of Trace: If A a square matrix, we can obtain \(A^T\) by interchanging the entries that are symmetriically positions about the main diagonal. Example
trace of A is: \(tr(A) = tr(A^T)= -1 +7+(-6)=0\)
- Inner and Outer Product: If \(u\) and \(v\) are column vectors with the same size, then \(u^Tv\) is the inner product of \(u\) and \(v\); if \(u\) and \(v\) are column vectors of any size, the \(uv^T\) is the outer product of \(u\) and \(v\).
Example inner product:
\[u = \begin{vmatrix} -1\\ 3 \\ \end{vmatrix} , v = \begin{vmatrix} 2\\ 5 \\ \end{vmatrix} , u^Tv =\begin{vmatrix} -1 &&3\\ \end{vmatrix} \begin{vmatrix} 2\\ 5 \\ \end{vmatrix} = -1.2 + 3.5 =13\]Example outer product
\[uv^T =\begin{vmatrix} -1 \\ 3\\ \end{vmatrix} \begin{vmatrix} 2 && 5 \\ \end{vmatrix}= \begin{vmatrix} -1.2 && -1.5 \\ 3.2 && 3.5 \end{vmatrix}= \begin{vmatrix} -2 && -5 \\ 6 && 15 \end{vmatrix}.\]- Cross product: In mathematics, the cross product or vector product (occasionally directed area product, to emphasize its geometric significance) is a binary operation on two vectors in a three-dimensional oriented Euclidean vector space , and is denoted by the symbol × . Given two linearly independent vectors a and b, the cross product, a × b (read “a cross b”), is a vector that is perpendicular to both a and b, and thus normal to the plane containing them. (wiki). Where \([a]_{\times}\) is skew-symmetric matrix
1.2 Points, vectors, and coordinate systems.
The most fundamental elements in space are points and vectors. Points have no length or volume, and connecting two points creates a vector, which can be thought of as an arrow pointing from one point to another. It’s important to note that a vector should not be confused with its coordinates, as a vector is one thing in space, such as “a,” and does not need to be associated with several real numbers. We can naturally talk about the plus or minus operation of two vectors without relating to any real numbers. Only when we specify a coordinate system in this 3D space can we talk about the vector’s coordinates in this system, finding several real numbers corresponding to this vector.
1.3 Rotation Vectors and Euler Angles
Homogeneous coordinates are a 4D vector with \(R\) as a rotation matrix, and \(t\) as translation.
\[\begin{vmatrix} R && t \\ 0^T && 1 \end{vmatrix}\]This set of transform matrices is also known as the special Euclidean group:
\[SE(3) = \bigg\{ T = \begin{vmatrix} R && t \\ 0^T && 1 \end{vmatrix}\in R^{4\times4} | R \in SO(3), t \in R^3 \bigg\}\]Rodrigues’ rotation formula: In the theory of three-dimensional rotation, Rodrigues’ rotation formula, named after Olinde Rodrigues, is an efficient algorithm for rotating a vector in space, given an axis and angle of rotation. By extension, this can be used to transform all three basis vectors to compute a rotation matrix in SO(3), the group of all rotation matrices, from an axis–angle representation. (Wiki)
Consider a rotation represented by \(R\). If described by a rotation vector, assuming that the rotation axis is a unit-length vector \(n\) and the angle is \(\theta\), then the vector \(\theta n\) can also describe this rotation.
\[R = cos\theta I + (1-cos\theta)nn^T + sin\theta [n]_\times\]Where \([n]_\times\) is vector to skew-symmetric conversion, \(I\) is the identiy matrix
- Euler Angles and Quaternions
II. What is Eigen 3?
Eigen3 is a C++ template library for linear algebra, providing functionality for matrices, vectors, numerical solvers, and related algorithms. It offers a simple and intuitive interface for performing basic matrix and vector operations. Eigen3 utilizes expression templates, a technique that optimizes the evaluation of mathematical expressions
2.1 Install Eigen3
To install Eigen3 on Ubuntu, you can follow these general steps:
- Open a terminal: Open a terminal on your Ubuntu system.
- Update the package list: Run the command
sudo apt update
to update the package list. - Install Eigen3: Run the command
sudo apt install libeigen3-dev
to install the Eigen3 library. - Verify installation: To verify that Eigen3 has been installed correctly, you can run a simple C++ program that includes the Eigen3 header file and performs a basic linear algebra operation.
sudo apt-get install mlocate sudo locate eigen3
Normally, the Eigen3 package installed in this directory:
/usr/include/eigen3
2.2 Eigen summarized (more detail )
- Rotation matrix (3x3):
Eigen::Matrix3d
- Rotation vector (3x1):
Eigen::AngleAxisd
- Euler angle (3x1):
Eigen::Vector3d
- Quaternion (4x1):
Eigen::Quaterniond
- Euclidean transformation matrix (4x4):
Eigen::Isometry3d
- Affine transform (4x4):
Eigen::Affine3d
- Perspective transformation(4x4):
Eigen::Projective3d
Basic working with matrix and matrix operation by run an example eigenMatrix.cpp
III. Practice with Eigen
3.1 Code structure
This tutorial shows how to build a simple C++ project with Eigen. We start with some simple code snipsets:
eigenMatrix.cpp
The basic code snipset for using matrix operator in Eigen.useGeometry.cpp
This code snipset demonstrates how to use the Eigen geometry module.coordinateTransform.cpp
….
├── helloworld
│ ├── build
│ │ ├── **/*.so --> library files
| | ├── **/*.a --> executable files
│ ├── CMakeList.txt
│ ├── eigenMatrix.cpp
│ ├── useGeometry.cpp
│ ├── coordinateTransform.cpp
- Add to the
CMakeLists.txt
CMakeLists.txt
# Add CMake Version
cmake_minimum_required(VERSION 2.8)
# Name of project
project(helloEigen)
# Add header file
include_directories("/usr/include/eigen3")
# Add executable
add_executable(eigenMatrix eigenMatrix.cpp)
add_executable(useGeometry useGeometry.cpp)
add_executable(coordinateTransform coordinateTransform.cpp)
- Config
c_pp_propertive
in VSCode{ "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/usr/include/eigen3" ], "defines": [], "compilerPath": "/usr/bin/clang", "cStandard": "c17", "cppStandard": "c++14", "intelliSenseMode": "linux-clang-x64" } ], "version": 4 }
- To run the code, following these command
mkdir build && cd build cmake .. make sudo ldconfig
3.2 Example Eigen with matrix definition
eigenMatrix.cpp
//Eigen core
#include <Eigen/Core>
//Algebraic operations of dense matrices (inverse, eigenvalues, etc)
#include <Eigen/Dense>
using namespace Eigen;
int main(int argc , char **argv){
//---------Declare Matrix Type-----------
// All vector and matrices in Eigen are Eigen::Matrix,
// Its first 3 parameters are: data type, row, collum.
// Example Declare a 2*3 float matrix
Matrix<float, 2, 3> matrix_23;
// 3D vector the same with matrix 3x1
Vector3d v_3d;
// This is the same
Matrix<float , 3, 1> vd_3d;
// Define 3x3 zeros matrix
Matrix3d matrix_33 = Matrix3d::Zero();
// If you are not sure about the size of the matrix,
// you can use the dynamic size
Matrix<double, Dynamic, Dynamic> matrix_dynamic;
//Or simpler way
MatrixXd matrix_x;
//---------In/Out Matrix data -----------
//Input data
cout << "Input matrix 2x3 from 1 to 6: " << endl;
for(int i=0; i <2; i++){
for(int j=0; j<3; j++)
cin >> matrix_23(i,j);
}
//Output
cout << "matrix 2x3 from 1 to 6: \n" << matrix_23 << endl;
// Use () to access elements in the matrix
cout << "print matrix 2x3: " << endl;
for(int i=0; i <2; i++){
for(int j=0; j<3; j++)
cout << matrix_23(i,j) << "\t";
cout << endl;
}
}