-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathfromTransfMatrixToPosQuat.m
89 lines (74 loc) · 3.41 KB
/
fromTransfMatrixToPosQuat.m
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
function q = fromTransfMatrixToPosQuat(H)
% FROMTRANSFMATRIXTOQUATERNIONS computes a link pose using position
% + quaternion rapresentation. The input is
% the link pose represented by a transformation matrix.
%
% FORMAT: q = fromTransfMatrixToPosQuat(H)
%
% INPUT: - H = [4 * 4] transf matrix representing link pose
%
% OUTPUT: - q = [7 * 1] position + quaternions representing link pose
%
% Authors: Daniele Pucci, Marie Charbonneau, Gabriele Nava
%
% all authors are with the Italian Istitute of Technology (IIT)
% email: [email protected]
%
% Genoa, Dec 2017
%
%% --- Initialization ---
% Separate the rotation matrix
R = H(1:3,1:3);
qt_b = zeros(4,1);
% min. value to treat a number as zero
epsilon = 1e-12;
% Compute the corresponding (unit) quaternion from a given rotation matrix R:
%
% The transformation uses the computational efficient algorithm of Stanley.
% To be numerically robust, the code determines the set with the maximum
% divisor for the calculation.
%
% For further details about the Stanley Algorithm, see:
% [1] Optimal Spacecraft Rotational Maneuvers, John L. Junkins & James D. Turner, Elsevier, 1986, pp. 28-29, eq. (2.57)-(2.59).
% [2] Theory of Applied Robotics: Kinematics, Dynamics, and Control, Reza N. Jazar, 2nd Edition, Springer, 2010, p. 110, eq. (3.149)-(3.152).
% Note: There exist also an optimized version of the Stanley method and is the fastest
% possible computation method for Matlab, but it does not cover all special cases.
% Further details about the fast calculation can be found at:
% [3] Modelling and Control of Robot Manipulators, L. Sciavicco & B. Siciliano, 2nd Edition, Springer, 2008,
% p. 36, formula (2.30).
%
tr = R(1,1) + R(2,2) + R(3,3);
if (tr > epsilon)
% scalar part:
qt_b(1,1) = 0.5*sqrt(tr + 1);
s_inv = 1/(qt_b(1,1)*4);
% vector part:
qt_b(2,1) = (R(3,2) - R(2,3))*s_inv;
qt_b(3,1) = (R(1,3) - R(3,1))*s_inv;
qt_b(4,1) = (R(2,1) - R(1,2))*s_inv;
else
% if tr <= 0, find the greatest diagonal element for calculating
% the scale factor s and the vector part of the quaternion
if ((R(1,1) > R(2,2)) && (R(1,1) > R(3,3)))
qt_b(2,1) = 0.5*sqrt(R(1,1) - R(2,2) - R(3,3) + 1);
s_inv = 1/(qt_b(2,1)*4);
qt_b(1,1) = (R(3,2) + R(2,3))*s_inv;
qt_b(3,1) = (R(2,1) + R(1,2))*s_inv;
qt_b(4,1) = (R(3,1) + R(1,3))*s_inv;
elseif (R(2,2) > R(3,3))
qt_b(3,1) = 0.5*sqrt(R(2,2) - R(3,3) - R(1,1) + 1);
s_inv = 1/(qt_b(3,1)*4);
qt_b(1,1) = (R(1,3) - R(3,1))*s_inv;
qt_b(2,1) = (R(2,1) + R(1,2))*s_inv;
qt_b(4,1) = (R(3,2) + R(2,3))*s_inv;
else
qt_b(4,1) = 0.5*sqrt(R(3,3) - R(1,1) - R(2,2) + 1);
s_inv = 1/(qt_b(4,1)*4);
qt_b(1,1) = (R(2,1) - R(1,2))*s_inv;
qt_b(2,1) = (R(3,1) + R(1,3))*s_inv;
qt_b(3,1) = (R(3,2) + R(2,3))*s_inv;
end
end
% Final state converted into quaternion rapresentation
q = [H(1:3,4); qt_b];
end