一、

在机器人位姿变换领域一个常识就是对于旋转来说,是不可交换次序的,而位置变换是可以交换位置的。

但是即使这样,我们也经常会陷入一个误区。例如绕x轴旋转30度,再绕着z轴旋转45度,最后绕着x轴旋转-30度。以公式表示就是下面这种形式:

R=rot_x(30)*rot_z(45)*rot_x(-30)

因为我们在单纯看到这个矩阵乘法的公式,会从矩阵相似到矩阵相等中分析,以求通过A和B都是旋转矩阵来找到他们相等的证据。然而事实证明他们确实不会相等[废话刚才说过了]。从实践的角度出发,我又用matlab试验了下,果然也是一样的结论

%以轴A旋转30度得到对应的旋转矩阵R1
v1 = [1.0,2.0,3.0];
theta1 = 30;
R1 = angvec2r(theta1, v1);
%以轴B旋转45度得到对应的旋转矩阵R2
v2 = [3.1,2.3,1.4];
theta2 = 45;
R2 = angvec2r(theta2, v2);

real_R2 = R2
computation_R2 = inv(R1)*R2*R1

得到的结果如下:

而其实我们知道,如果刚好我们的A和B是绕着坐标系的某轴旋转得到的其实是欧拉角,例如上面说的就是X-Z-X欧拉角。

二、

但是如果我们要从机器人的角度去看到这件事,我们可以以什么什么视角去审视呢?

假设以上的公式成立,也就是 A^-1*B*A=B成立,式子中的B和A分别是两个不同的旋转矩阵。那么我们设基座标系O,首先将B作用到O上面就得到的就是这个样子:

然后这时,我们在B的基础上,也就是以B坐标系为基座标系,A为在B坐标系下的旋转。将A作用到B上之后就会得到这样的姿态:

现在就来重点了,那这个A-1表示的是什么几何意义呢

我们知道一句话,叫做“右乘联体,左乘基”,这句话的意思是指当我们想要通过一系列旋转矩阵确定末端位姿相对于基座标系的表示形式时,一般来说有两种表述方法,一种是相对于联体坐标系,比如上面的BA,就是指A要右乘B才可以得到A相对于基座标系的位姿;另一种是相对于基座标系,即每一次新的旋转都是相对于基座标系的。

如果这么看来虽然我们经过旋转B得到了B相对于O的姿态了,但是下一个旋转我们仍然是相对于基座标系O的,这个时候就需要左乘,即是这个样子:

A^(-1)*O*B*A

显然,由于我们是相对于基座标系旋转了 A-1,而不是相对于A坐标系旋转A-1,那么最终的得到的姿态肯定不是原来的B,也就是说,上面那个等式肯定不能成立。

但是我们仍然需要注意,在实际中我们是在得到这个整体的旋转之后才作用到O的,因此这里实际应用用联体坐标系的旋转做法去理解更接近实际。也就是说,对于基座标系首先旋转A^(-1),然后再转B再转A。

O*A^(-1)*B*A

三、

既然我们已经分析了这么多,那么什么时候上面的公式可以成立呢?

那显然就是先转B,再在B的基础上旋转BA的逆,最后再转BA。

这里可以这么分析是因为i对于旋转来说,BA^(-1)和BA对应的是同一个旋转轴,的不同角度[下面代码显示的是反向的轴,相同角度。一样理解],因此可以先看后面两个旋转即:

BA^(-1)*BA

最后再得到

O*BA^(-1)*BA*BA*BA = B

%以轴A旋转30度得到对应的旋转矩阵R1
v1 = [1.0,2.0,3.0];
theta1 = 30;
R1 = angvec2r(theta1, v1);
%以轴B旋转45度得到对应的旋转矩阵R2
v2 = [3.1,2.3,1.4];
theta2 = 45;
R2 = angvec2r(theta2, v2);
[zheng_shaft,zheng_angle] = tr2angvec(R1*R2)
[ni_shaft,ni_angle] = tr2angvec(inv(R1*R2))

May the force be with you!