分解旋转矩阵(x,y',z'') - 笛卡尔角

时间:2016-08-24 16:28:42

标签: matlab rotational-matrices cartesian decomposition

分解旋转矩阵(x,y',z'') - 笛卡尔角

我目前正在使用旋转矩阵,我遇到以下问题: 给定三个坐标系(O0,x0,y0,z0; O1,x1,y1,z1; O2,x2,y2,z2)重合。我们首先相对于帧#0旋转帧#1,然后相对于帧#1旋转帧#2。

轮换顺序:R = Rx_alpha * Ry_beta * Rz_gamma,首先关于 x ,然后 y' ,然后 z'' ,也称为笛卡尔角度。 如果R1代表第一轮,R2代表第二轮的R2,我们在两个旋转后寻找第二帧相对于初始帧(#0)的角度。这可以通过分解旋转矩阵 R(其中:R = R1*R2)来完成。有许多文献可供参考,如何通过欧拉和RPY角度来完成,但我没有找到任何,如何在笛卡尔角的情况下解决这个问题。

我有一个 matlab函数,只能通过简单的旋转。如果所有角度的值都不是0(例如下面的例子),那么结果就会变得非常不稳定。

第一帧相对于帧#0的方向:

    alpha1 = 30*pi/180;
    beta1 = 10*pi/180;
    gamma1 = 0*pi/180;

第2帧相对于帧#1的方向

    alpha2 = 10*pi/180;
    beta2 = 10*pi/180;
    gamma2 = 0*pi/180;

我用来解决问题的matlab函数:

function [q] = cartesian_angles(R)

beta = asin(R(1,3));

*% Catching the numerical singularty*
if abs(abs(beta)-pi/2) > eps;
    *% singulartiy of acos*
    gamma1 = acos(R(1,1) / cos(beta));
    gamma2 = asin(-R(1,2) / cos(beta));
    if gamma2<0
        gamma=2*pi-gamma1;
    else
        gamma=gamma1;
    end
    alpha1 = acos(R(3,3) / cos(beta));
    alpha2 = asin(-R(2,3) / cos(beta));
    if alpha2<0
        alpha = 2*pi-alpha1;
    else
        alpha = alpha1;
    end
else
    fprintf('beta=pi/2 \n')
    gamma = 0;
    alpha = 0;
    beta  = 0;
end;

alpha = alpha*180/pi;
beta = beta*180/pi;
gamma = gamma*180/pi;

q = [alpha; beta; gamma];

感谢您的帮助!如果您有一些问题,请不要犹豫!

马尔西

2 个答案:

答案 0 :(得分:0)

首先,我假设你正在将一个条件良好的右手旋转矩阵传递给你的函数。我将使用与上面列出的相同的旋转顺序,X Y'Z''

如果你知道旋转矩阵的符号结构,你试图从中提取角度,那么数学就很简单了。下面是一个matlab代码示例,用于确定X-Y'-Z''的旋转矩阵的构造

a = sym('a');%x
b = sym('b');%y
g = sym('g');%z

Rx = [1 0 0;0 cos(a) -sin(a);0 sin(a) cos(a)];
Ry = [cos(b) 0 sin(b);0 1 0;-sin(b) 0 cos(b)];
Rz = [cos(g) -sin(g) 0;sin(g) cos(g) 0;0 0 1];

R = Rz*Ry*Rx

输出如下:

R =

[ cos(b)*cos(g), cos(g)*sin(a)*sin(b) - cos(a)*sin(g), sin(a)*sin(g) + cos(a)*cos(g)*sin(b)]
[ cos(b)*sin(g), cos(a)*cos(g) + sin(a)*sin(b)*sin(g), cos(a)*sin(b)*sin(g) - cos(g)*sin(a)]
[       -sin(b),                        cos(b)*sin(a),                        cos(a)*cos(b)]

以更好看的格式得到的结果相同:

enter image description here

现在让我们回顾一下从这个矩阵中提取角度。现在是熟悉atan2()函数的好时机。

首先求解β角(顺便说一句,alpha是围绕X轴的旋转,β是围绕Y'轴的旋转,而gamma是围绕Z'轴的角度):

beta = atan2(-1*R(3,1),sqrt(R(1,1)^2+R(2,1)^2))

写得更正式,

enter image description here

现在我们已经解决了β角度,我们可以更简单地解决其他两个角度:

alpha = atan2(R(3,2)/cos(beta),R(3,3)/cos(beta))
gamma = atan2(R(2,1)/cos(beta),R(1,1)/cos(beta))

简化并以更好的格式

enter image description here

enter image description here

上述方法是一种非常强大的方法,可以将Euler角度从旋转矩阵中取出。 atan2功能确实使它更简单。

最后,我将回答一系列旋转后如何求解旋转角度。首先考虑以下符号。矢量或旋转矩阵将以下列方式标记:

enter image description here

这里“U”代表通用框架或全局坐标系。 “Fn”表示与U不同的第n个局部坐标系.R表示旋转矩阵(该表示法也可用于均匀变换)。左侧上标将始终表示旋转矩阵或向量的父参考框架。左侧下标表示子参考框架。例如,如果我在F1中有一个向量,并且我想知道它在通用参考框架中的等效性,那么我将执行以下操作:

enter image description here

为了在通用框架中解析向量,我简单地将它乘以将事物从F1转换为U的旋转矩阵。注意下标中下一项的上标如何“取消”下标。这是一个聪明的符号,可以帮助别人搞清楚事情。如果你还记得,条件良好的旋转矩阵的一个特殊性质是逆矩阵是矩阵的转置,这也是这样的逆变换:

enter image description here

现在说明符号细节已经不在了,我们可以开始考虑解决复杂的旋转系列。假设我有“n”个坐标系(另一种说法是“n”不同的旋转)。为了找出通用框架中“第n”帧中的向量,我将执行以下操作:

enter image description here

要确定由“n”旋转产生的Cardan / Euler角度,您已经知道如何分解矩阵以获得正确的角度(在某些字段中也称为反向运动),您只需要正确的矩阵。在这个例子中,我对旋转矩阵感兴趣,旋转矩阵将事物放在“第n”坐标系中并将它们解析为通用框架U:

enter image description here

有它,我只是通过乘以正确的顺序将所有旋转组合成感兴趣的旋转。这个例子很简单。当有人想要在另一个框架中找到一个刚体的参考框架时,会出现更复杂的情况,这两个刚体的共同点就是它们在通用框架中的测量。

我还要注意,这种表示法和方法也可以用于同构变换,但有一些关键的区别。旋转矩阵的逆是它的转置,对于均匀变换不是这样。

答案 1 :(得分:0)

感谢您回答willpower2727,您的回答非常有帮助!

但我想提一下,你所展示的代码对于分解旋转矩阵很有用,它们是按照以下方式构建的:

R = Rz*Ry*Rx

我在寻找:

R = Rx*Ry*Rz

这导致以下旋转矩阵:

Rotational Matrix

但是,这不是问题,因为按照计算角度alpha,beta和gamma的方法,很容易修改代码,因此它会分解上面显示的矩阵。

角度:

beta = atan2(  R(1,3), sqrt(R(1,1)^2+(-R(1,2))^2) )
alpha = atan2( -(R(2,3)/cos(beta)),R(3,3)/cos(beta) )
gamma = atan2( -(R(1,2)/cos(beta)),R(1,1)/cos(beta) )

但有一点仍然不清楚。该方法非常有用,只有在我计算一次旋转后的角度时才会使用。由于有更多的旋转相互连接,结果是错误的。但是,考虑到以下方法,它仍然是可以解决的:假设我们有两个旋转相互连接(R1和R2)。 q1表示R2的R1,q2的角度。分解单个矩阵后。矩阵R=R1*R2的总旋转角度可以通过总结之前的范围来轻松计算:q=q1+q2

有没有办法,怎么计算总旋转角度,不是通过求和偏角,而是分解矩阵R=R1*R2

更新:

考虑以下基本示例。旋转相互关联:

a1 = 10*pi/180
b1 = 20*pi/180
g1 = 40*pi/180
R1 = Rx_a1*Ry_b1_Rz_g1

a2 = 20*pi/180
b2 = 30*pi/180
g2 = 30*pi/180
R2 = Rx_a2*Ry_b2*Rz_g2

分解各个矩阵R1和R2会产生权利角度。问题发生时,当我将旋转链接到彼此之后,我试图确定惯性框架中最后一帧的角度。从理论上讲,这可以通过分解变换链的所有旋转矩阵的乘积来完成。

R = R1*R2

分解此矩阵会产生以下度数显示的以下错误结果:

a = 0.5645
b = 54.8024
g = 61.4240

马尔西