1、空间描述与变换

有两个坐标系A和B,B坐标系中有一个点P,如何把B坐标系中的P映射到A坐标系呢,这就涉及到空间描述与变换,

先看一下旋转矩阵:

上面中间的行向量中的元素表示在B坐标系当中的元素用A坐标系来表达。

是B坐标原点在A坐标系中的表达,它也是平移量;AP表示P在A坐标系中的表达,BP表示P在坐标系B中的表达。

要想将BP转换为A坐标系中的表达,就需要乘以旋转矩阵,它是旋转量。

下面目的是将B坐标系中的P点在A坐标系中进行表达

将它可以写成齐次坐标的形式如下,

中间的表达式可以成为旋转算子,

首先,看一下xyz固定角坐标系:

首先将一个坐标系B与一个已知坐标系A重合,先将B坐标系绕XA坐标系逆时针旋转γ角度,这里X轴坐标不变;然后再绕YA坐标轴逆时针旋转β角度;最后绕ZA轴逆时针旋转α角度。每一次旋转都是按照对应的固定参考系。我们将这种姿态的表示方法叫做X-Y-Z固定角坐标系。有时也叫偏航角,横滚角,俯仰角。

再来看一下欧拉表示法:

首先将一个坐标系B与一个已知坐标系A重合,首先将B坐标系绕ZA轴逆时针旋转α角度;再绕YA坐标轴逆时针旋转β角度;最后绕XA坐标系逆时针旋转γ角度。这个与上面的区别在于,每次旋转都是绕着坐标系B中的坐标轴旋转而不是绕着坐标系A中的坐标旋转。

最后来看一下四元素表示法:

与矩阵相比四元组更加高效,占用的空间更小,且便于插值。四元组表示复数,w+xi+yj+zk,其中i,j,k都是虚数单位。可以把四元组看做是一个标量和一个3维向量的组合;实部w表示标量,虚部(x,y,z)用v表示。其中w与旋转角度相关,v与旋转轴相关。

操作四元组,欧拉角或者X-Y-Z固定角可以用Bullet方法,KDL::Rotation方法等

tf

tf的原理

有三个坐标系,一个未知坐标系query,已知坐标系known,一个世界坐标系world

要求得未知坐标系在世界坐标系当中的表达,可以用旋转算子来表示:

未知坐标系在世界坐标系中的旋转算子=未知坐标系在已知坐标系中的旋转算子*已知坐标系在世界坐标系中的旋转算子,通过例子来看一下,

1、roscore

2、roslaunch turtle_tf turtle_tf_demo.launch

出现两只乌龟一只乌龟随着另外一只乌龟跑,

一只乌龟跟随另一只乌龟的运动而运动,这里面就包含三个坐标系,一个是乌龟1坐标系,一个是乌龟2坐标系,还有一个世界坐标系,

使用命令行工具,

view frames是以pdf的形式来展示运行框架的,

rosrun tf view_frames

打开该pdf,如下

turtle1和turtle2的父坐标系均为world坐标系。

然后再看,

下面看一下turtle1与turtle2作为之间的关系,前者作为父坐标系,后者作为子坐标系

再看一下tf_monitor工具

仍然以turtle1作为父框架,turtle2作为子框架

可以看到上面从turtle1到turtle2的变换的相关信息

TransformBroadcaster有一个方法sendTransform它可以提供的信息是已知坐标系到世界坐标系的旋转算子。

TransformListener提供了一个方法lookupTransform提供了一个未知坐标系到一个已知坐标系的旋转算子。

ExtrapolationException异常是两个frame之间存在请求,但是其中有一个frame是过时的,例如turtle1在listen时请求的是turtle2在50秒之前的请求,则会无效。

编写程序实现turtle tf_demo那个例子

打开eclipse,导入工程,然后新建一个源文件turtle_tf_broadcaster.cpp

#include<ros/ros.h>

#include<tf/transform_broadcaster.h>

#include<turtlesim/Pose.h>//turtlesim广播的是一个位姿消息,包括位置和角度

//定义一个全局变量,用于在命令行中输入turtle的名字

std::string turtle_name;

//回调函数的消息为turtlesim的msg

void posecallback(turtlesim::PoseConstPtr &msg)

{

  //创建一个TransformBroadcaster存储变换的相关信息

  static tf::TransformBroadcaster br;

  //接着创建一个对象Transform存储变换的相关信息,它包含旋转和位移的信息,有一个向量叫做Vector3表示坐标,以及四元组表示方向

  tf::Transform transform;

  //下面把turtlepose的相关信息copy到transform中,通过transform在tf树中进行广播,

  transform.setOrigin(tf::Vector3(msg->x,msg->y,0));

  //创建一个四元组

  tf::Quaternion q;

  //调用它的方法,因为它是绕着z轴旋转故有下面参数形式

  q.setRPY(0,0,msg->theta);

//为transform的rotation赋值

  transform.setRotation(q);

  //然后再广播出去,创建一个transform::stamped对象

  br.sendTransform(tf::StampedTransform(transform,ros::Time::now(),"world",turtle_name));

}

int main(int agc,char **argv)

{

  ros::init(argc,argv,"turtle_tf_broadcaster");

  if(argc!=2)

  {

    ROS_ERROR("need turtle name as argument.");

    return -1;

  }

  turtle_name=argv[1];//传递进来的名字

  ros::NodeHandle node;

  //下面创建一个subscriber订阅对象,订阅的主题是turtle_name+"/pose",列表长度为10,回调函数为posecallback

  ros::Subscriber sub=node.subscribe(turtle_name+"/pose",10,&posecallback);

  ros::spin();

  return 0;

}

下面修改CMakeLisets.txt文件

add_executable(turtle_tf_broadcaster  src/turtle_tf_broadcaster.cpp)

target_link_libraries(turtle_tf_broadcaster ${catkin_LIBRARIES})

第六课 ROS的空间描述和变换的更多相关文章

  1. 第八课 ROS的空间描述和变换

    1.tf的实际应用 1)在机器人的配置中 从上面可以看出激光雷达中心距离机器人底座的中心有20cm,激光雷达的中心距机器人底座中心有10cm,如果激光雷达在障碍物前面0.3米,那么机器人底座离障碍物多 ...

  2. 第七课 ROS的空间描述和变换

    在命令行工具中也有一个与transformcaster相类似的工具叫做static_transform_publisher,它能够接受命令行参数来接受位置信息.旋转信息.父框架.子框架以及周期信息,通 ...

  3. Coursera公开课笔记: 斯坦福大学机器学习第六课“逻辑回归(Logistic Regression)” 清晰讲解logistic-good!!!!!!

    原文:http://52opencourse.com/125/coursera%E5%85%AC%E5%BC%80%E8%AF%BE%E7%AC%94%E8%AE%B0-%E6%96%AF%E5%9D ...

  4. NeHe OpenGL教程 第三十六课:从渲染到纹理

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  5. NeHe OpenGL教程 第二十六课:反射

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  6. NeHe OpenGL教程 第五课:3D空间

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  7. 【Linux探索之旅】第一部分第六课:Linux如何安装在虚拟机中

    内容简介 1.第一部分第六课:Linux如何安装在虚拟机中 2.第二部分第一课预告:终端Terminal,好戏上场 Linux如何安装在虚拟机中 虽然我们带大家一起在电脑的硬盘上安装了Ubuntu这个 ...

  8. 【C语言探索之旅】 第二部分第六课:创建你自己的变量类型

    内容简介 1.课程大纲 2.第二部分第六课: 创建你自己的变量类型 3.第二部分第七课预告:   文件读写 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C ...

  9. information_schema系列六(索引,表空间,权限,约束相关表)

    information_schema系列六(索引,表空间,权限,约束相关表) 1: STATISTICS 这个表提供的是关于表的索引信息:   INFORMATION_SCHEMA Name SHOW ...

随机推荐

  1. poj 1028 Web Navigation 【模拟题】

    题目地址:http://poj.org/problem?id=1028 测试样例: Sample Input VISIT http://acm.ashland.edu/ VISIT http://ac ...

  2. 算法思考: poj 1969 Count on Canton

                                      A - Count on Canton Time Limit:1000MS     Memory Limit:30000KB     ...

  3. kafka常用的shell命令

    kafka常用shell命令: ------------------------------------ 1.创建topic bin/kafka-topics.sh --create --zookee ...

  4. Java -- 容器使用 Set, List, Map, Queue, Collections

    1. ArrayList ArrayList<String> c = new ArrayList<String>(); c.add("hello"); c. ...

  5. linux新增用户和删除用户

    新增用户 新增用户命令:useradd 参数: 参数 说明 -u 指定UID,也就是自定义UID -g 知道GID,也就是初始化用户组,/etc/passwd文件中的第四个字段. -G 后面接用户组的 ...

  6. php之定义大字符串数据时使用定界符来标识

    在定义大字符串数据时,通常使用定界符来标识,这种方式能保留文本中的格式,如文本中的换行.定界符使用格式如下. <<<identifier 格式化文本 identifier 其中,符号 ...

  7. 程序以html形式发送邮件注意问题

    1.样式要写在内部,不要单独定义样式 2.div 使用背景图片在有些浏览器中出不来这时候需要用: <table style="width: 640px" cellpaddin ...

  8. Javascript中 节流函数 throttle 与 防抖函数 debounce

    问题的引出 在一些场景往往由于事件频繁被触发,因而频繁地进行DOM操作.资源加载,导致UI停顿甚至浏览器崩溃. 在这样的情况下,我们实际上的需求大多为停止改变大小n毫秒后执行后续处理:而其他事件大多的 ...

  9. Java微信开发_Exception_03_errcode:48001 errmsg:api unauthorized hint

    创建菜单时出现这个异常, 异常信息:errcode:48001 errmsg:api unauthorized hint 解读:调用的接口没有权限. 回去公众号后台一看,发现真的没有自定义菜单的权限, ...

  10. Linux-Rsync命令参数详解

    在对rsync服务器配置结束以后,下一步就需要在客户端发出rsync命令来实现将服务器端的文件备份到客户端来.rsync是一个功能非常强大的工具,其命令也有很多功能特色选项,我们下面就对它的选项一一进 ...