问题背景:在根据《机器人导论》这本书的Z-Y-X欧拉角原理用Matlab实现旋转矩阵求解时,发现与直接调用机器人工具箱中的rpy2tr()函数得出的结果并不相同。

首先:先检查自己写的函数是否有错。根据其原理:坐标系B可以用如下方式表示——先将坐标系B和一个已知参考坐标系A重合,先将B绕B的Z轴转afa角,再绕B的Y轴转beta角,最后绕B的X轴转gama角。所以得到的旋转矩阵就是R=Rz*Ry*Rx。

代码如下:

 %afa:绕着z轴的旋转角——yaw;beta:绕着y轴的旋转角——pitch;gama:绕着x轴的旋转角——roll(都是角度制)
%机器人工具箱里面提供的函数是rpy2tr()(是弧度制)——且对应的角度是:roll—pitch—yaw function R=EularToR(afa, beta,gama) Rz=[cosd(afa), -sind(afa), 0; sind(afa), cosd(afa), 0; 0, 0, 1]; %afa是绕z轴旋转,偏航角——yaw
Ry=[cosd(beta),0, sind(beta);0, 1, 0; -sind(beta), 0, cosd(beta)];%beta是绕y轴旋转,俯仰角——pitch
Rx=[1, 0, 0; 0, cosd(gama), -sind(gama); 0, sind(gama), cosd(gama)];%gama是绕x轴旋转,翻滚角——roll R=Rz*Ry*Rx;

发现应该没有什么问题。

再次:理解Matlab中rpy2tr函数的实现方式

function T = rpy2tr(roll, varargin)

    R = rpy2r(roll, varargin{:});
T = r2t(R);

转入rpy2r(roll, varargin{:})函数继续查看

function R = rpy2r(roll, varargin) 
%varargin提供了一种函数可变参数列表机制,
%允许调用者调用该函数时根据需要来改变输入参数的个数 %设置默认参数
opt.zyx = false;
opt.deg = false;
[opt,args] = tb_optparse(opt, varargin); % unpack the arguments
if numcols(roll) ==
pitch = roll(:,);%pitch(y)应该是输入参数的第二个值
yaw = roll(:,);%yaw(z)应该是输入参数的第三个值
roll = roll(:,);%roll(x)应该是输入参数的第一个值
elseif nargin >= 3%还不太理解这一段的意思
pitch = args{};
yaw = args{};
else
error('RTB:rpy2r:badarg', 'bad arguments')
end % optionally convert from degrees考虑如果输入的参数是角度,且已经将"deg"作为选项输入函数,需将角度转化为弧度
if opt.deg
d2r = pi/180.0;
roll = roll * d2r;
pitch = pitch * d2r;
yaw = yaw * d2r;
end if ~opt.zyx
% XYZ order如果是先绕着X轴,再Y轴,最后Z轴旋转的话,是如下的矩阵相乘顺序
if numrows(roll) ==
R = rotx(roll) * roty(pitch) * rotz(yaw);
else
R = zeros(,,numrows(roll));
for i=:numrows(roll)
R(:,:,i) = rotx(roll(i)) * roty(pitch(i)) * rotz(yaw(i));
end
end
else
% old ZYX order (as per Paul book)如果是先绕着Z轴,再Y轴,再X轴旋转的话,又将是不同的相乘顺序
if numrows(roll) ==
R = rotz(roll) * roty(pitch) * rotx(yaw);
else
R = zeros(,,numrows(roll));
for i=:numrows(roll)
R(:,:,i) = rotz(roll(i)) * roty(pitch(i)) * rotx(yaw(i));
end
end
end

结论:理解完rpy2tr函数,我们发现了问题所在,这是因为存在两种不同的旋转顺序,导致不一样的矩阵相乘顺序,所以最终得出的旋转矩阵也不一样。

感悟:要多去读源代码!才能彻底领会这些函数的使用方法和实现原理。

最新文章

  1. 利用反射手写代码实现spring AOP
  2. 如何在Eclipse中查看JDK的源代码
  3. yii2整合百度编辑器umeditor
  4. 给文件加ip访问限制
  5. jquery的ajax向ashx传值,中文乱码问题
  6. 【HAOI2006】【BZOJ1051】【p1233】最受欢迎的牛
  7. php中echo、print、print_r、printf的返回值
  8. Delphi消息的广播方式(先RegisterWindowMessage,后SendMessage HWND_BROADCAST,最后改写接收窗口的WndProc)
  9. windows服务(Windows Installer问题,错误5:拒绝访问)
  10. Android读取Assert文件夹下txt文本并变为String的方法
  11. 排列组合相关算法 python
  12. JavaWeb总结(二)—HttpServletResponse对象
  13. 【算法】螺旋方阵 上交OJ1021
  14. SpringBoot系列——i18n国际化
  15. C# System.IO.File
  16. java 多线程 25 :线程和线程组的异常处理
  17. [原]unity3d之http多线程异步资源下载
  18. 为什么每次进入命令都要重新source /etc/profile 才能生效?
  19. 关于函数strtok和strtok_r的使用要点和实现原理(一)【转】
  20. wap 往下拉自动加载更多数据

热门文章

  1. Postgresql ERROR: permission denied for relation app_info
  2. 【Fiddler学习】Fiddler抓包HTTPS请求和手机抓包
  3. <项目管理的决策力>总结梳理
  4. Ruby学习笔记2 : 一个简单的Ruby网站,搭建ruby环境
  5. iOS 第三方应用调用safari
  6. openStack queens 功能验证调试
  7. java中定义的四种类加载器
  8. NetBeans 8以后版本无法连接git服务器
  9. BBS-基于forms组件和ajax实现注册功能
  10. ABAP-异常捕获