首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >旋转矢量转换为旋转矩阵的罗德里格斯公式

旋转矢量转换为旋转矩阵的罗德里格斯公式
EN

Stack Overflow用户
提问于 2021-02-19 14:29:40
回答 1查看 2.9K关注 0票数 2

我试图理解三维旋转矢量到旋转矩阵的转换。假设我有一个三维旋转向量a,b,g。从Trucco等人的“3D计算机视觉入门技术”中,我相信我可以把它表示为每个轴x,y,z的旋转矩阵的乘积。

但是更多的时候,我看到这种从旋转矢量到矩阵的转换,使用的是罗德里格斯公式,在下面的图像中给出了A.17

我正在Matlab中测试这两种方法(我使用的是执行罗德里格斯函数的Matlab图像处理工具箱中内置的rotationVectorToMatrix函数),对于小角色,我得到的结果非常接近。

代码语言:javascript
运行
复制
alpha = 1 * (pi/180);
beta = 2 * (pi/180);
gamma = 3 * (pi/180); 
R = [(cos(beta) * cos(gamma)) (-cos(beta)*sin(gamma)) sin(beta);
 sin(alpha) * sin(beta) * cos(gamma) + cos(alpha)*sin(gamma) ...
  -sin(alpha) * sin(beta) * sin(gamma) + cos(alpha) * cos(gamma) ...
  -sin(alpha) * cos(beta); ...
  -cos(alpha)*sin(beta)*cos(gamma) + sin(alpha)*sin(gamma) ...
  cos(alpha) * sin(beta) * sin(gamma) + sin(alpha) * cos(gamma) ...
  cos(alpha) * cos(gamma)]

 Rm = rotationVectorToMatrix([alpha beta gamma])'

我得到了

代码语言:javascript
运行
复制
R =

    0.9980   -0.0523    0.0349
    0.0529    0.9984   -0.0174
   -0.0339    0.0193    0.9985
Rm = 
    0.9980   -0.0520    0.0353
    0.0526    0.9985   -0.0165
   -0.0344    0.0184    0.9992

但是,当我的角度变大时,它们会有点发散,例如,如果我做了

代码语言:javascript
运行
复制
alpha = 10 * (pi/180);
beta = 20 * (pi/180);
gamma = 30 * (pi/180);

我得到了

代码语言:javascript
运行
复制
R =

    0.8138   -0.4698    0.3420
    0.5438    0.8232   -0.1632
   -0.2049    0.3188    0.8529


Rm =

    0.8089   -0.4578    0.3689
    0.5166    0.8530   -0.0742
   -0.2807    0.2506    0.9265

再一次,我只是想得到一个更好的理解,这些方法是从旋转向量转换成矩阵等价的吗?我应该一直用罗德里格斯的方法吗?如果是的话,为什么?谢谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-19 19:19:09

“旋转矢量”假定角度是同时的。因此,使用欧拉角是不合适的比较,假设顺序的角度。对于小角度,你会得到一些接近,但对于较大的角度,它将得到显著的差异。

一个恰当的比较将是四元数,它也假设同时的角度,在同样的意义上,一个旋转矢量。所以就像

代码语言:javascript
运行
复制
V = [alpha beta gamma];
angle = norm(V);
q = [cos(angle/2) sin(angle/2)*V/angle];

那就拿这个做比较。例如,

代码语言:javascript
运行
复制
quat2dcm(q)

编辑

如果您没有MATLAB航天工具箱,那么您可以手动完成此转换。航天工具箱使用标量向量顺序,右链,右手汉密尔顿惯例.因此,转换将是:

代码语言:javascript
运行
复制
qw = q(1); qv = q(2:4); % note qv is a row vector here
skew = @(v)[0 -v(3) v(2);v(3) 0 -v(1);-v(2) v(1) 0];
dcm = (qw^2 - qv*qv')*eye(3) + 2*qv'*qv - 2*qw*skew(qv) % right-chain Hamilton

机器人工具箱使用的是左链约定,因此,如果您要比较工具箱中的函数,则需要翻转交叉乘积项的符号。例如,

代码语言:javascript
运行
复制
dcm = (qw^2 - qv*qv')*eye(3) + 2*qv'*qv + 2*qw*skew(qv) % left-chain Hamilton

如果你比较左撇子四元数惯例(又名JPL),交叉乘积项会在翻转符号上倾斜。所以它归结为

代码语言:javascript
运行
复制
% right-chain right-handed Hamilton OR left-chain left-handed JPL
dcm = (qw^2 - qv*qv')*eye(3) + 2*qv'*qv - 2*qw*skew(qv)

% left-chain right-handed Hamilton OR right-chain left-handed JPL
dcm = (qw^2 - qv*qv')*eye(3) + 2*qv'*qv + 2*qw*skew(qv)

右链是指在三重四元数旋转操作(通常用于两个不同坐标系之间的被动坐标系转换)中,未修改的四元数出现在右侧:

代码语言:javascript
运行
复制
vnew = q^-1 * v * q

左链是指在三重四元数旋转操作中,未修改的四元数出现在左侧(通常用于在同一坐标系内的主动矢量旋转):

代码语言:javascript
运行
复制
vnew = q * v * q^-1

右撇子意味着四元数的虚单位像正则交叉积项一样相乘。例如,

代码语言:javascript
运行
复制
i * j = k
j * k = i
k * i = j

左撇子意味着四元数的虚单位像正则交叉积项的负数一样相乘。也就是说,就像一个左手坐标系。例如,

代码语言:javascript
运行
复制
i * j = -k
j * k = -i
k * i = -j

当然,如果您使用的是向量-标量顺序的四元数,则需要从上面取出标量和向量部分。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66279458

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档