Rotation Matrix – Mathematical Theory

Table of Contents

Overview

1. Fixed rotation (Fix Angles)

2. Euler Angle

3. Summary of rotation matrix

4. Reference


Overview

The rotation matrix is a mathematical expression of posture, or generally speaking, the transformation matrix is an abstract mathematical variable. Its abstraction lies in the fact that when you see the data, you can’t judge its correctness at all; often you can only convert it into a more intuitive Euler angle, and then roughly estimate it visually (you can’t use a protractor to measure the accuracy). We know that the mathematical forms of posture include rotation matrix (satisfying R^t*R=E), Euler angle, rotation vector (angular axis), four Elements(norm(x y z w) = 1) etc. What we will discuss here today is the theoretical basis related to rotation matrices.

Rotation matrices are commonly used in the following three scenarios:

  • Describe the pose of one frame (coordinate system) relative to another frame; (for example: describe the camera movement between two adjacent frames)
  • Describes the transformation of a point from one frame to another frame; (In fact, the point does not move, but the coordinates are different when observed in the two frames; such as:; the coordinates of the landmark point P are different in different camera coordinate systems, but in the world It is fixed in the coordinate system)
  • Describes the movement of a point in the same frame; (the point here is in motion and is rarely used in VSLAM)

Please remember the rotation matrix around the three axes in the following form. Some places may be in the transposed form below.

(This blog, like most paper materials, is based on the left multiplication principle)

1. Fixed rotation (Fix Angles)

The so-called fixed rotation is to rotate according to a fixed axis outside the object. This kind of rotation is very common in engineering and is used relatively frequently (compared to the Euler rotation in Chapter 2). For example, if the rotation order is X-Y-Z, then the form of the rotation matrix is: RZ*RY*RX. As shown below, there is actually not much to say. The picture below shows how to solve the rotation matrix given three Euler angles.

Given the rotation matrix, how to solve for Euler angles? We know that 180° clockwise rotation and 180° counterclockwise rotation are equivalent (rotating the robotic arm 190° is actually a long way to go, because rotating 170° seems faster), so the value of the calculated Euler angle is The best range is: [0°, 180°] or [0°, -180°] or [-90°, 90°], the latter is used here.

atan2 in the code below is the API in matlab. Here we simply verify the difference between it and tan: you can see that when a point is in the third quadrant, such as (-1, -1), in the Euler angle, The angle is: -135°, but atan(-1/-1) calculates 45°, which is obviously wrong.

>> atan(1) * 180 / pi

ans =

    45

>> atan2(1, 1) * 180/pi

ans =

    45

>> atan2(-1, -1) * 180/pi

ans =

  -135

>>

Please verify it with Eigen here: (Relevant header files (such as Pose.h Pose.cpp) can be found in this link: Pose conversion based on Eigen – CSDN blog) Do not download it, you can run the following C++ code No more

#include"Pose.h"
#include<iostream>
using namespace std;

int main()
{
    Eigen::Matrix3d R1;
    R1 << 0.866, 0.433, 0.25, 0., 0.5, -0.866, -0.5, 0.75, 0.433;

    Pose pose1(R1);
    cout << "Rotation matrix = " << endl; cout << pose1.rotation() << endl;
    cout << "Euler angle = " << endl; cout << pose1.euler_angle().transpose()*(180 / M_PI) << endl;
    cout << "Quaternion = " << endl; cout << pose1.quaternion().coeffs().transpose() << endl;
    cout << "Angle axis = " << endl;
    cout << pose1.angle_axis().angle()* (180 / M_PI) << " " << pose1.angle_axis().axis().transpose() << endl;
    cout << "-----------------------------" << endl;
    return 1;
}

Print the result:

Rotation matrix = 0.866 0.433 0.25
            0 0.5 -0.866
            -0.5 0.75 0.433
Euler angle = 63.4349 14.4779 -26.5651
Quaternion = 0.482959 0.224145 -0.129407 0.836511
Angular axis = 66.4519 0.881411 0.409071 -0.23617

You can see that Eigen’s Euler angle results are different from the results calculated by Matlab in the above PPT, but their rotation matrices are exactly the same. This is normal and will be encountered below. In fact, it is solved using the Euclidean rotation matrix. The solution to Euler angles is not unique. This problem has been verified in hand-eye calibration.

The figure below shows how to solve Euler angles given the rotation matrix.

2. Euler Rotation (Euler Angle)

The relationship between fixed rotation and Euler rotation, for example: Fixed rotation The order is: >The order is: ZYX. When written as a rotation matrix, it is: Rz*Ry*Rx. The final mapping matrix is the same, but the process is different. Different paths lead to the same end. ) such as the following example:

I have actually “experienced” ZYZ’s Euler rotation sequence. It was on a certain robot arm where the teach pendant was data. The way of Euler rotation is as follows:

The shape is like a fixed rotation. I also give here: ZYZ type Euler rotation, a method to solve Euler angles:

For the above equation:

Use Eigen to verify here, for the left side of the equation:

1 #include"Pose.h"
 2 #include<iostream>
 3 using namespace std;
 4
 5 int main()
 6 {
 7 // Low-level error: It is 60.0, not 60
 8 Eigen::Matrix3d R1;
 9 R1 = Eigen::AngleAxisd(60.0 / 180 * M_PI, Eigen::Vector3d::UnitX()) *
10 Eigen::AngleAxisd(30.0 / 180 * M_PI, Eigen::Vector3d::UnitY()) *
11 Eigen::AngleAxisd(0.0, Eigen::Vector3d::UnitZ());
12
13 Pose pose3(R1);
14 cout << "Rotation matrix = " << endl; cout << pose3.rotation() << endl;
15 cout << "Euler angle = " << endl; cout << pose3.euler_angle().transpose()*(180 / M_PI) << endl;
16 cout << "Quaternion = " << endl; cout << pose3.quaternion().coeffs().transpose() << endl;
17 cout << "Angle axis = " << endl;
18 cout << pose3.angle_axis().angle()* (180 / M_PI) << " " << pose3.angle_axis().axis().transpose() << endl;
19 cout << "-----------------------------" << endl;
22 return 1;
23}

For the right side of the equation, the same is true:

#include"Pose.h"
#include<iostream>
using namespace std;

int main()
{
    Eigen::Vector3d RPY;
    RPY << -56.3 / 180 * M_PI, 64.3 / 180 * M_PI, 73.9 / 180 * M_PI;

    cout << RPY(2, 0) << endl;


    Eigen::Matrix3d R2;
    // note: ZYZ
    R2 = Eigen::AngleAxisd(RPY(0, 0), Eigen::Vector3d::UnitZ()) *
         Eigen::AngleAxisd(RPY(1, 0), Eigen::Vector3d::UnitY()) *
         Eigen::AngleAxisd(RPY(2, 0), Eigen::Vector3d::UnitZ());
    Pose pose4(R2);
    cout << "Rotation matrix = " << endl; cout << pose4.rotation() << endl;
    cout << "Euler angle = " << endl; cout << pose4.euler_angle().transpose()*(180 / M_PI) << endl;
    cout << "Quaternion = " << endl; cout << pose4.quaternion().coeffs().transpose() << endl;
    cout << "Angle axis = " << endl;
    cout << pose4.angle_axis().angle()* (180 / M_PI) << " " << pose4.angle_axis().axis().transpose() << endl;
    cout << "-----------------------------" << endl;

    return 1;
}

Comparing the two rotation methods, you can see that the results calculated by Eigen are completely consistent (the numerical difference is a little bit different, which engineering people understand, and it is normal and acceptable); but what is more interesting is that for the following, the Euler angle I used It is obviously (-56.3, 64.3, 73.9) (ZYZ), and the result is printed out. The Euler angle is actually (59.9, 29.99, 0.031). This is because at the bottom of the Pose class I wrote, I only defined the fixed rotation method of ZYX. At the same time, it also explains that the same rotation matrix may correspond to different rotation methods (such as Euler rotation, fixed rotation), different rotation Euler angles, and even different rotation orders.

3. Summary of rotation matrix

The valid permutations and combinations of Euler rotation and fixed rotation are: 12 = 3 * 2 * 2

The mathematical form of attitude includes rotation matrix (constraint: RTR=E), Euler angle (universal lock problem), rotation vector (angular axis), quaternion (constraint norm(x y z w) = 1), so VSLAM is in alignment When optimizing the posture,

In order to avoid the “constrained optimization” problem, the rotation vector is generally used as the posture.

4. Reference

(Kinematics of Robotics at National Taiwan University – Lin Peiqun)